gpt4 book ai didi

haskell - 单子(monad)和抽象

转载 作者:行者123 更新时间:2023-12-03 14:56:57 29 4
gpt4 key购买 nike

我是haskell、函数式语言和monads的新手。
我已经搞砸了大约一个月;我读了
learn you a haskell
并且正在玩 snap 试图制作我的 haskell 网站。

但是有一些事情让我感到困扰:monads 抽象。
如果我理解正确,单子(monad)是可以排序的“数据容器”。
例如,我可以用“>>=”“解包”它,更多的工作将在“幕后”完成
对我来说,如果我没有 monad 定义,我必须猜测它将如何解包。

例如:

我们有一个列表单子(monad),解压它会对其元素进行排序

[1,2,3] >>= return . (+1) -- gives back [2,3,4]

或者像这些例子中的作者这样更复杂的单子(monad):
Log Writer Monad

或者我可能有一个 webWriter monad,对于它的每个“解包”它的值,它都会向某个远程服务器发送一个请求(我不确定这个,但我试图给出一个极端的情况)

我的问题是:我能否仅通过查看 monad 用户界面(我猜是类型定义)来判断 apply 函数('>>='、'applyLog')在幕后做什么?

希望我能很好地解释自己。

谢谢,奥伦。

最佳答案

虽然你不知道是什么(>>=)仅通过查看界面就可以为特定的 monad 做事,每个 monad 都必须遵守规则才能构成“适当的” monad。这限制了 return 的可能实现。和 (>>=) . monad laws如下:

  • 左身份:return a >>= f等于 f a
  • 正确身份:m >>= return等于 m
  • 关联性:(m >>= f) >>= g等于 m >>= (\x -> f x >>= g)

  • 例如,如果 return List monad 被定义为 \x -> [x,x]而不是 \x -> [x] ,这将违反左身份定律。 return 5 >>= \x -> [x+1]将不同于 (\x -> [x+1]) 5 .

    另外, not all monads can be intuitively understood as 'containers' of some kind .容器类比适用于 List 和 Maybe,但是 Reader 呢? Reader 值并不真正“包含”任何东西。相反,它是对依赖于外部不变环境的计算的描述。

    Monad 是任何实现 monad 接口(interface)并遵守 monad 法则的东西。

    编辑:作为如何直观地了解 monad 实例对给定类型所做的示例,请考虑 Data.Stream.Infinite.Stream来自 streams包裹。流就像列表,只是它们总是无限的。

    Stream 有一个 Monad 实例。什么会 return(>>=)在这种情况下怎么办?
    return类型为 a -> Stream a .这种类型唯一可能的函数是返回作为参数传递的值的无限重复的函数。
    (>>=)更棘手。它的类型为 Stream a -> (a -> Stream b) -> Stream b .这种类型的一个可能的函数是接受第一个参数的头部并将其应用于第二个参数,返回结果流的函数。 s >>= f = f $ head s .
    (>>=) 的另一种可能实现将是应用 a -> Stream b 类型的函数到原始流的每个元素,得到 Stream (Stream b) 类型的中间结果, 然后以某种方式将流折叠成单个 Stream b值(value)。怎么做?您可以简单地取无限正方形的对角线!

    哪个版本的 (>>=)是否符合单子(monad)定律?第一个当然不会,因为它破坏了正确的身份。 1,2,3,4... >>= return 的结果将是 1,1,1,1... .第二个实现尊重正确的身份(你明白为什么吗?),这让我们更加确信它可能是实现 (>>=) 的正确方法。对于流。当然,您需要所有法律的实际证明才能确定!

    关于haskell - 单子(monad)和抽象,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18710246/

    29 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com