-- MonadicStack.hs (Learn You a Haskell for Great Good!) | -- DesugaredMonadicStack.hs (Learn You a Haskell for Great Go import Control.Monad.State import Control.Monad.State type Stack = [Int] type Stack = [Int] pop :: State Stack Int | pop :: State Stack Int -- The following line was wrong in the book: | pop = -- pop = State $ \(x:xs) -> (x,xs) | get >>= pop = do | \(x:xs) -> put xs >> x:xs <- get < put xs < return x return x push :: Int -> State Stack () | push :: Int -> State Stack () -- The following line was wrong in the book: | push a = -- push a = State $ \xs -> ((),a:xs) | get >>= push a = do | \xs -> put (a:xs) >> xs <- get < put (a:xs) < return () return () pop1 = runState pop [1..5] pop1 = runState pop [1..5] push1 = runState (push 1) [2..5] push1 = runState (push 1) [2..5] stackManip :: State Stack Int stackManip :: State Stack Int stackManip = do | stackManip = push 3 | push 3 >> a <- pop | pop >>= pop | \a -> pop stackManip1 = runState stackManip [5,8,2,1] stackManip1 = runState stackManip [5,8,2,1] stackManip2 = runState stackManip [1,2,3,4] stackManip2 = runState stackManip [1,2,3,4] stackStuff :: State Stack () stackStuff :: State Stack () stackStuff = do | stackStuff = a <- pop | pop >>= if a == 5 | \a -> then push 5 | if a == 5 then else do | push 5 push 3 | else push 8 | push 3 >> > push 8 stackStuff1 = runState stackStuff [9,0,2,1,0] stackStuff1 = runState stackStuff [9,0,2,1,0] stackStuff2 = runState stackStuff [5,4,3,2,1] stackStuff2 = runState stackStuff [5,4,3,2,1] moreStack :: State Stack () moreStack :: State Stack () moreStack = do | moreStack = a <- stackManip | stackManip >>= if a == 100 | \a -> then stackStuff | if a == 100 then else return () | stackStuff > else > return () moreStack1 = runState moreStack [100,9,0,2,1,0] moreStack1 = runState moreStack [100,9,0,2,1,0] moreStack2 = runState moreStack [9,0,2,1,0] moreStack2 = runState moreStack [9,0,2,1,0] > moreStack3 = runState moreStack [100,5,4,3,2,1] stackyStack :: State Stack () stackyStack :: State Stack () stackyStack = do | stackyStack = stackNow <- get | get >>= if stackNow == [1,2,3] | \stackNow -> then put [8,3,1] | if stackNow == [1,2,3] then else put [9,2,1] | put [8,3,1] > else > put [9,2,1] stackyStack1 = runState stackyStack [1,2,3] stackyStack1 = runState stackyStack [1,2,3] stackyStack2 = runState stackyStack [10,20,30,40] | stackyStack2 = runState stackyStack [10,20,30,40]