好吧,我不是 Haskell 程序员,但我对 Haskell 背后的很多想法非常感兴趣,并且正在考虑学习它。但我陷入了第一个困境:我似乎无法理解 Monad,这似乎是相当基本的。我知道有上百万个问题要求解释 Monad,所以我将更具体地说明困扰我的问题:
我读了这篇优秀的文章(JavaScript 简介 http://blog.jcoglan.com/2011/03/05/translation-from-haskell-to-javascript-of-selected-portions-of-the-best-introduction-to-monads-ive-ever-read/),并认为我完全理解 Monads 了。然后我读了维基百科关于 Monads 的条目,看到了这个:
多态类型 (M t)→(t→M u)→(M u) 的绑定操作,Haskell 用中缀运算符 >>= 表示。它的第一个参数是一元类型中的值,第二个参数是一个从第一个参数的基础类型映射到另一个一元类型的函数,并且它的结果是另一个一元类型。
好的,在我引用的文章中,bind 是一个函数,它需要only one争论。维基百科说有两个。我什么thought我对 Monad 的理解如下:
- Monad 的目的是采用具有不同输入和输出类型的函数并使其可组合。它通过使用单个单子类型包装输入和输出类型来实现此目的。
- Monad 由两个相互关联的函数组成:bind 和 unit。 Bind 接受一个不可组合的函数 f 并返回一个新函数 g,该函数接受单子类型作为输入并返回单子类型。 g 是可组合的。 unit 函数接受 f 期望的类型的参数,并将其包装在 monadic 类型中。然后可以将其传递给 g 或 g 等函数的任何组合。
但肯定有什么问题,因为我的绑定概念只有一个参数:一个函数。但是(根据维基百科)Haskell 的绑定实际上需要two争论!我的错误在哪里?
你没有犯错误。这里要理解的关键思想是柯里化——两个参数的 Haskell 函数可以用两种方式来看待。第一个只是两个参数的函数。例如,如果您有,(+)
,这通常被视为采用两个参数并将它们相加。另一种看待它的方式是作为加法机生产商。(+)
是一个需要数字的函数,比如说x
,并创建一个函数来添加x
.
(+) x = \y -> x + y
(+) x y = (\y -> x + y) y = x + y
在处理 monad 时,有时可能更好,正如上面提到的,考虑=<<
,翻转版本>>=
。有两种方法可以看待这个问题:
(=<<) :: (a -> m b) -> m a -> m b
这是两个参数的函数,并且
(=<<) :: (a -> m b) -> (m a -> m b)
正如文章中提到的,它将输入函数转换为易于编写的版本。这些是等价的,就像(+)
正如我之前所解释的。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)