Nothing is perfect. Even though a tremendous effort must have been taken to create LYAH )1 I found it very confusing - for a long time. Since, I understand Haskell more and more I just realised that there is also code
LYAH )1 is stating here:
import Control.Monad.State pop :: State Stack Int pop = State $ \(x:xs) -> (x,xs) push :: Int -> State Stack () push a = State $ \xs -> ((),a:xs)
pop is already a stateful computation and push takes an Int and returns a stateful computation. Now we can rewrite our previous example of pushing 3 onto the stack and then popping two numbers off like this:
import Control.Monad.State stackManip :: State Stack Int stackManip = do push 3 a <- pop pop
a ← pop is “assigning” a state to a binding (“variable”) a but a will never be picked up, and the with just pop discards the result completely.app\Main.hs:28:5: warning: [-Wunused-matches]
Defined but not used: `c'
|
mm | c <- pop
| ^
app\Main.hs:33:5: warning: [-Wunused-do-bind]
A do-notation statement discarded a result of type `Int'
Suppress this warning by saying `_ <- pop'
|
nn | pop
| ^^^
Linking .stack-work\...
app\Main.hs:21:10: error:
Not in scope: data constructor `S.State'
Perhaps you meant one of these:
`S.StateT' (imported from Control.Monad.State),
variable `S.state' (imported from Control.Monad.State)
Module `Control.Monad.State' does not export `State'.
|
21 | push a = S.State $ \xs -> ((),a:xs)
|
pops in stackManip then you get the following runtime error:pop = S.state $ \(x:xs) → (x,xs)LYAH )1 Learn You a Haskell for Great Good!