在最近的作业中,我被要求为某些非列表类型定义折叠函数。我还没有完全理解这个概念。到目前为止,我已将fold
理解为执行list
中的后续元素。 fold
上的Tree
仍然具有直观意义,因为人们可以在根的子树上递归地应用某些函数。
但是,在类似的数据类型上:
Maybe a :: Nothing | Just a
执行折叠操作时没有list
(在我看来)。
我确定在理解这里的基本概念方面存在一些问题,我非常感谢一些清理工作。
答案 0 :(得分:6)
Foldable
是一个非常令人困惑的课程,说实话,因为它没有很多法律,很可能写出很多不同的{{1}几乎任何给定类型的实例。幸运的是,根据相同类型的Traversable
实例(如果有的话),可以找出Foldable
实例应该以纯机械方式执行的操作。
我们有
Foldable
class (Functor t, Foldable t) => Traversable t where
traverse :: Applicative f => (a -> f b) -> t a -> f (t b)
有几个不同的法律,但事实证明最重要的是Traversable
。我们来看看这适用于traverse Identity = Identity
:
Maybe
现在,在第一种情况下,您需要生成traverse :: Applicative f => (a -> f b) -> Maybe a -> f (Maybe b)
traverse g Nothing = _none
traverse g (Just a) = _some
,而您拥有的只是f (Maybe b)
。由于您没有任何g :: a -> f b
值,并且您没有任何f
值,因此您唯一可以生成a
。
在第二种情况下,您必须生成pure Nothing
并且您拥有f (Maybe b)
和g :: a -> f b
。因此,唯一有趣的方法是将a
应用于g
,获取a
。现在你有两个选择可以考虑:你可以抛弃这个值,然后只返回g a :: f b
,或者你可以把它包装在Nothing
中。
根据身份法,Just
。因此,您不得返回traverse Identity (Just a) = Identity (Just a)
。 仅法律定义是
Nothing
traverse _ Nothing = pure Nothing
traverse g (Just a) = Just <$> g a
的{{1}}实例完全取决于Traversable
定律和参数。
现在可以使用Maybe
折叠:
Traversable
这适用于traverse
,
foldMapDefault :: (Traversable t, Monoid m)
=> (a -> m) -> t a -> m
foldMapDefault f xs =
getConst (traverse (Const . f) xs)
扩展我们的定义,
Maybe
根据foldMapDefault f Nothing =
getConst (traverse (Const . f) Nothing)
foldMapDefault f (Just a) =
getConst (traverse (Const . f) (Just a))
的{{1}}和foldMapDefault f Nothing = getConst (pure Nothing)
foldMapDefault f (Just a) = getConst (Just <$> (Const (f a)))
的定义,这些是
pure
展开构造函数,
<$>
这确实是为Const
定义foldMapDefault f Nothing = getConst (Const mempty)
foldMapDefault f (Just a) = getConst (Const (f a))
的原因。
答案 1 :(得分:3)
As&#34;基本概念&#34;去,这是非常令人费解的,所以不要感觉太糟糕。
将折叠对列表的作用放在一边,并考虑 type 特定的折叠函数(让我们使用foldr
)应该具有的帮助可能会有所帮助如果应用于Maybe
。写List a
代替[a]
以使其更清晰,列表上的标准foldr
具有类型:
foldr :: (a -> b -> b) -> b -> List a -> b
显然,Maybe上的相应折叠必须有类型:
foldrMaybe :: (a -> b -> b) -> b -> Maybe a -> b
考虑一下这可能有什么定义,因为必须为所有a
和b
定义,而不知道有关类型的任何其他内容。作为进一步的提示,看看Data.Maybe
中已经定义了一个类似类型的函数 - 也许(哈哈),它会给你一些想法。