很明显,如果一个数据结构是一个monoid,它是可折叠的,但是可以确定地说一个数据结构是可折叠的,它是monoid吗?
https://en.wikibooks.org/wiki/Haskell/Foldable
如果数据结构是可折叠的,那么它是一个monoid吗?
答案 0 :(得分:21)
您的主张“如果数据结构是Monoid
,那么它就是Foldable
”,这是不合理的。例如:
newtype ActionList a = ActionList (IO [a])
instance Monoid (ActionList a) where
mempty = ActionList (return [])
ActionList a `mappend` ActionList b = ActionList (liftA2 (++) a b)
这是一个非常好用的类人动物。但是,由于其所有值都在IO
下,因此您无法从Foldable
观察到它们中的任何一个。唯一的Foldable
实例将是一个总是返回空的实例(从技术上讲,这是有效的,因为foldMap
确实没有关于其有效性的任何定律,但是很难说这是一个好例子。具有直脸的实例)。
您要问的相反情况也不正确。例如:
data TwoThings a = TwoThings a a
这是可折叠的:
instance Foldable TwoThings where
foldMap f (TwoThings x y) = f x <> f y
但是,如果以任何相关方式同时是Foldable
和Monoid
的话,我希望以下同态定律成立:
foldMap f mempty = mempty
foldMap f (a <> b) = foldMap f a <> foldMap f b
我们无法使这些法律适用于TwoThings
。请注意,foldMap (:[]) a
的{{1}}始终具有两个元素。但是第二定律在左边有两个元素,在右边有四个元素。但是,dfeuer's answer显示,不需要法律来找到反例。
答案 1 :(得分:6)
这里有些Foldable
(甚至是Traversable
)也不希望成为Monoid
的希望:
{-# language EmptyCase #-}
data F a
instance Foldable F where
foldMap _ t = case t of
-- or, = mempty
instance Traversable F where
traverse _ t = case t of
-- or, = pure $ case t of
instance Semigroup (F a) where
-- the only option
x <> _ = x
instance Monoid (F a) where
mempty = ????