【发布时间】:2016-01-08 06:45:12
【问题描述】:
我只是想获得单子,所以如果我问了一个不好的问题,请耐心等待,但是...
如果单子只需要:
-
(a -> M a),其中 M 是一元类型构造函数,并且 -
(M a -> (a -> M b) -> M b),这是绑定操作(我理解为将单子映射到非单子到单子值函数)
...这是否意味着:
-
(M a -> a)和 -
(M (M a) -> M a)不是隐式必需的吗?
这通常不会引起问题吗?
假设我们有一组函数 S,它们的类型都是
(x -> y),其中 x 和 y 是任意类型。现在,假设我使用一组单子函数 M 进行编程,其中它们的类型是
x -> M y。
这是否意味着一旦我将一个类型转换为M y,我就不能使用任何(x -> y) 函数? 或者,我可以假设我可以做到(M x -> (x -> y) -> (y -> M y) -> M y)吗?
另外,我们在编程的时候不是一般都想提取原始类型吗?在async a -> a 或maybe a -> a 之类的东西之间切换时……这不是常见的操作吗?我绝对可以看到有人想要优化一个 monad 的情况,如果他们认为它可以忽略不计(例如,一个 logging monad)。
此外,没有扁平化的分层 monad 怎么样?我知道列表可以被视为限制展平的单子,这是一个明确且合乎逻辑的选择,但是async (async a) 单子值的假设情况如何,async 没有展平功能? bind 是否只意味着一层“一元还原”,我们通常可以假设(M a -> (a -> M a) -> M a) 通常可以视为(M a -> (M a -> a) -> (a -> M a) -> M a),而(M M a -> (a -> M a) -> M a or M M a) 可能不起作用?扁平化和非扁平化单子之间有真正的区别吗?
【问题讨论】:
-
这个问题最好发布在cstheory.stackexchange.com 而不是这里。 Stack Overflow 更多的是关于实际编程问题。
-
M a -> a不是必需的。并不是所有的 monad 都需要支持它。M (M a) -> M a可以派生自return和bind(即M a -> (a -> M b) -> M bBTW)。 -
@n.m.所以这意味着我不能使用
(a -> b)类型的函数集S?如果我需要将我的整个函数集引入单子函数集,这是否意味着我必须通过在某处应用单子构造函数来手动转换每个(a -> b) -> (a -> M b)? -
如果你曾经写过一个做 IO 的 Haskell 程序,你就知道你不必手动将每个函数都转换成
a->IO b,. -
您可以用
bind或flatten定义任何monad。这两种方式是等价的。如果你有bind,你可以用bind来定义flatten,反之亦然。
标签: monads