在我看来,著名问题"What is a monad?"的答案,特别是投票最多的问题,试图解释什么是monad,而没有清楚地解释为什么monad真的是必要的。它们能被解释为问题的解决方案吗?
发布于 2016-06-19 08:16:22
单体基本上是将函数组合在一起形成一个链。句号。
现在,它们的组合方式在现有的monad中是不同的,因此导致了不同的行为(例如,在状态monad中模拟可变状态)。
关于monads的混乱之处在于,由于monads是如此通用,即一种组合函数的机制,它们可以用于许多事情,从而导致人们认为monads是关于状态、关于IO等的,而它们只是关于“组合函数”。
现在,关于monad的一个有趣的事情是,合成的结果总是"M a“类型,也就是说,用"M”标记的信封内的值。这个特性恰好可以很好地实现,例如,在纯代码和不纯代码之间进行清晰的分离:将所有不纯操作声明为"IO a“类型的函数,并且在定义IO monad时不提供从"IO a”内部取出"a“值的函数。结果是,没有一个函数可以是纯的,同时从"IO a“中取出一个值,因为没有办法在保持纯的同时获取这样的值(函数必须在"IO”monad中才能使用这样的值)。(注意:没有什么是完美的,所以可以使用"unsafePerformIO : IO a -> a“打破"IO约束”,从而污染本应是纯函数的东西,但这应该非常谨慎地使用,并且当您真正知道不会引入任何具有副作用的不纯代码时。
发布于 2015-07-23 22:31:16
Monads只是一个用于解决一类重复出现的问题的方便框架。首先,monads必须是functors (即必须支持映射而不查看元素(或其类型)),它们还必须带来绑定(或链接)操作和从元素类型(return
)创建一元值的方法。最后,bind
和return
必须满足两个等式(左等式和右等式),也称为单数定律。(或者,可以将monads定义为具有flattening operation
而不是绑定。)
list monad通常用于处理非确定性。绑定操作选择列表中的一个元素(直观地说,所有元素都在并行世界中),让程序员对它们进行一些计算,然后将所有世界中的结果组合到单个列表中(通过连接或扁平嵌套列表)。下面是如何在Haskell的一元框架中定义置换函数:
perm [e] = [[e]]
perm l = do (leader, index) <- zip l [0 :: Int ..]
let shortened = take index l ++ drop (index + 1) l
trailer <- perm shortened
return (leader : trailer)
下面是一个repl会话示例:
*Main> perm "a"
["a"]
*Main> perm "ab"
["ab","ba"]
*Main> perm ""
[]
*Main> perm "abc"
["abc","acb","bac","bca","cab","cba"]
应该注意的是,list monad绝不是影响计算的副作用。一个数学结构是一个单体(即符合上面提到的界面和定律)并不意味着副作用,尽管副作用现象通常很好地适合一元论框架。
https://stackoverflow.com/questions/28139259
复制相似问题