解释 Haskell monad 示例

Interpreting Haskell monad example

我有这个 Haskell 代码可以将输入值增加三倍。

triple :: Int -> Int
triple = do
  n <- id
  d <- (n+)
  (d+)

这段代码是如何工作的?举个例子triple 10,参数10如何从mapped/assigned到idnd得到return值30?

我的理解如下:

我们可以用两个子函数 tripleAtripleB 分解 triple 函数,如下所示:

triple :: Int -> Int
triple = tripleA >>= (\d -> tripleB d)

tripleA :: Int -> Int
tripleA = id >>= (\n -> (n+))

tripleB :: Int -> Int -> Int
tripleB d = (d+)

现在我们可以看到函数tripleA得到一个输入,将它赋给id函数给return值本身,映射到函数(\n -> (n+)) 到 return (10+) 10.

同样,tripleB 也使 (20+) 20,所以我预计结果为 40,但正确答案是 30。

我的解释有什么问题吗?

我们可以重写等价的 triple2 函数如下:

triple2 = (id >>= (\n -> (n+))) >>= (\d -> (d+))

有了 f = \n -> (n+),我们有 triple2 = (id >> f) >> f

根据(https://hackage.haskell.org/package/base-4.9.0.0/docs/src/GHC.Base.html#line-645)中>>=的定义,我们有

1。 id >>= f

\r -> f (id r) r = \r -> f r r = \r -> (r+) r

2。 (id >>= f) >>= f

x = id >>= f = \r -> (r+) r
x r = (r+) r
x >> f = \r -> f (x r) r = f ((r+) r) r = ((r+) r)+ r

所以((10+) 10)+ 10使得30