Monads和抽象

Cou*_*ren 6 monads haskell

我是haskell,功能语言和monad的新手.
我一直在乱搞这个约一个月; 我已经读过 你了解一个haskell 并且正在试图制作我的haskell网站.

但有些东西困扰着我:monads抽象.如果我理解正确,monad是可以排序的"数据容器".我可以用">> ="解压缩它,例如"幕后工作"将为我做更多工作,所以如果我没有monad定义,我必须猜测它将如何被解压缩.

例如:

我们有列表monad,解压缩它将对其元素进行排序

[1,2,3] >>= return . (+1) -- gives back [2,3,4]
Run Code Online (Sandbox Code Playgroud)

或者像这些例子中的作家那样更复杂的monad: Log Writer Monad

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

我的问题是:我是否可以通过查看monad用户界面(我猜是类型定义)告诉应用函数('>> =','applyLog')在幕后做什么?

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

谢谢,奥伦.

dan*_*iaz 8

虽然你(>>=)只是通过查看界面无法知道对于特定monad的作用,但是每个monad都必须遵守法律以构成"适当的"monad.这限制了return和的可能实现(>>=).该单子法律如下:

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

例如,如果return将List monad定义为\x -> [x,x]而不是\x -> [x],则会破坏Left身份法.return 5 >>= \x -> [x+1]会有所不同(\x -> [x+1]) 5.

此外,并非所有monad都可以被直观地理解为某种"容器".容器类比适用于List和Maybe,但是读者呢?Reader值并不真正"包含"任何内容.相反,它是对依赖于外部不变环境的计算的描述.

Monad是实现monad接口并尊重monad法则的任何东西.

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

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值.怎么做?你可以简单地采取无限广场的对角线!

哪个版本(>>=)与monad法律兼容?第一个肯定没有,因为它打破了正确的认同.结果1,2,3,4... >>= return将是1,1,1,1....第二个实现尊重正确的身份(你能看出原因吗?),这使我们更加确信它可能是实现(>>=)流的正确方法.当然,您需要确保所有法律的实际证据!