【问题标题】:How can I understand the laws for Foldable instances?如何理解可折叠实例的法律?
【发布时间】:2017-04-26 23:02:40
【问题描述】:

在描述 Data.Foldable 的页面上,它说: 可折叠实例应满足以下定律:

foldr f z t = appEndo (foldMap (Endo . f) t ) z
foldl f z t = appEndo (getDual (foldMap (Dual . Endo . flip f) t)) z
fold = foldMap id

请帮助我了解上述法律的运作方式。什么是Endo . f

【问题讨论】:

标签: haskell


【解决方案1】:

Endo 是“合成下的内同态幺半群”。 appEndo 是该类型的字段。

newtype Endo a = Endo { appEndo :: a -> a }

-- i.e.
Endo :: (a -> a) -> Endo a
appEndo :: Endo a -> (a -> a)

您可以将“endomorphism”视为输入和输出类型相同的函数的技术正确术语 (a -> a)。

EndoMonoid 的一个实例,其组成:

instance Monoid (Endo a) where
        mempty = Endo id
        Endo f `mappend` Endo g = Endo (f . g)

为了让规律更容易掌握,我们以List类型为例:

instance Foldable [a] where
    foldMap f []     = mempty
    foldMap f (x:xs) = f x `mappend` foldMap f xs

-- i.e.
-- foldMap f [a, b, …, w] == f a `mappend` f b `mappend` … `mappend` f w

当我们评估法律的 RHS 时:

   foldMap (Endo . f)         t
== foldMap (\x -> Endo (f x)) [a, b, …, w]
== (\x -> Endo (f x)) a `mappend`   …   `mappend` (\x -> Endo (f x)) w
== Endo (f a) `mappend` Endo (f b) `mappend`   …   `mappend` Endo (f w)

recall mappend for Endo 是作曲,所以上面是

== Endo (f a . f b .   …   . f w)

最后我们使用appEndo (…) z取出组合函数并将其应用到初始值z

   appEndo (Endo (f a . f b .   …   . f w)) z 
== (f a . f b .   …   . f w)                z
== f a (f b (  …  (f w z)  …  ))

这正是foldr 对列表的定义。


foldl 类似,Dual 是另一个幺半群实例,Dual a `mappend` Dual b == Dual (b `mappend` a)getDual 取出内部幺半群。应该很容易看出这是如何产生foldl 的。


fold 函数将可折叠的幺半群折叠成单个幺半群。再次以List为例,fold可以实现为

fold [a, b, …, w] == a `mappend` b `mappend` … `mappend` w

可以从foldMap检索到:

foldMap id [a, b, …, w] == id a `mappend` id b `mappend` … `mappend` id w
                        == a `mappend` b `mappend` … `mappend` w

这显示了身份fold = foldMap id 的建议方式。

【讨论】:

  • so Endo a 是由从 a 到 a 的 endo-maps 组成的集合吗?
  • @user28522 是的,直到同构。请注意,在类型中,Endo a 是此类映射的类型,而在(程序/表达式)方面,Endo 是同构的名称 (a->a) -> Endo a,而appEndo 是其逆 iso。
  • 我还是不明白:“......是同构的名称(a->a)-> Endo a,而appEndo是它的逆iso。”。请指出我可以查找更多信息以了解您所说的内容的地方。谢谢。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-01-12
  • 1970-01-01
  • 1970-01-01
  • 2023-03-14
  • 2017-08-12
相关资源
最近更新 更多