====== Confusing pop statement in LYAH ======
~~DISCUSSION~~
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
- which does not really make sense
- hence, generates warnings
- it also generates compiler errors, because of incompatibilities with new packages philosophies
- can generate runtime errors if the code would be extendend
LYAH )1 is stating [[http://learnyouahaskell.com/for-a-few-monads-more#state|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
- The line ''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.
- Hence, it creates compiler warning:
*
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\...
- The new package philosophy renamed the data type State to StateT (The StateT monad transformer).
*
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)
|
- If you use to much ''pop''s in ''stackManip'' then you get the following __**runtime**__ error:
* ...-exe...: app\Main.hs:xx:yy-zz: Non-exhaustive patterns in lambda
* which is this line ''pop = S.state $ \(x:xs) -> (x,xs)''
----
LYAH )1 Learn You a Haskell for Great Good!