问题
I have this Haskell code that triples input value.
triple :: Int -> Int
triple = do
n <- id
d <- (n+)
(d+)
How does this code work? With an example triple 10
, how the argument 10
is mapped/assigned to id
, n
and d
to get the return value of 30?
My understandig is as follows:
We can decompose triple
function with two subfunctions tripleA
and tripleB
as follows:
triple :: Int -> Int
triple = tripleA >>= (\d -> tripleB d)
tripleA :: Int -> Int
tripleA = id >>= (\n -> (n+))
tripleB :: Int -> Int -> Int
tripleB d = (d+)
Now we can see that the function tripleA
gets an input, assign it to id
function to return the value itself, and map it to the function (\n -> (n+))
to return (10+) 10
.
Likewise, tripleB also makes (20+) 20
, so I expect the results as 40, but the correct answer is 30.
What is wrong with my interpretation?
回答1:
We can rewrite equivalent triple2 function as follows:
triple2 = (id >>= (\n -> (n+))) >>= (\d -> (d+))
With f = \n -> (n+)
, we have triple2 = (id >> f) >> f
.
From the definition of >>=
in (https://hackage.haskell.org/package/base-4.9.0.0/docs/src/GHC.Base.html#line-645), we have
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
so ((10+) 10)+ 10
makes 30
来源:https://stackoverflow.com/questions/38626030/interpreting-haskell-monad-example