DESUGARED MONADIC 堆栈:
-- DesugaredMonadicStack.hs (Learn You a Haskell for Great Good!)
import Control.Monad.State
type Stack = [Int]
pop :: State Stack Int
pop =
get >>=
\(x:xs) -> put xs >>
return x
push :: Int -> State Stack ()
push a =
get >>=
\xs -> put (a:xs) >>
return ()
pop1 = runState pop [1..5]
push1 = runState (push 1) [2..5]
stackManip :: State Stack Int
stackManip =
push 3 >>
pop >>=
\a -> pop
stackManip1 = runState stackManip [5,8,2,1]
stackManip2 = runState stackManip [1,2,3,4]
stackStuff :: State Stack ()
stackStuff =
pop >>=
\a ->
if a == 5 then
push 5
else
push 3 >>
push 8
stackStuff1 = runState stackStuff [9,0,2,1,0]
stackStuff2 = runState stackStuff [5,4,3,2,1]
moreStack :: State Stack ()
moreStack =
stackManip >>=
\a ->
if a == 100 then
stackStuff
else
return ()
moreStack1 = runState moreStack [100,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 =
get >>=
\stackNow ->
if stackNow == [1,2,3] then
put [8,3,1]
else
put [9,2,1]
stackyStack1 = runState stackyStack [1,2,3]
stackyStack2 = runState stackyStack [10,20,30,40]
DESUGARED MONADIC RANDOM 生成器:
-- DesugaredMonadicRandomGenerator.hs (Learn You a Haskell for Great Good!)
import System.Random
import Control.Monad.State
randomSt :: (RandomGen g, Random a) => State g a
randomSt =
get >>=
\gen ->
let (value,nextGen) = random gen
in
put nextGen >>
return value
randomSt1 = (runState randomSt (mkStdGen 1)) :: (Int,StdGen)
randomSt2 = (runState randomSt (mkStdGen 2)) :: (Float,StdGen)
threeCoins :: State StdGen (Bool,Bool,Bool)
threeCoins =
randomSt >>=
\a -> randomSt >>=
\b -> randomSt >>=
\c -> return (a,b,c)
threeCoins1 = runState threeCoins (mkStdGen 33)
threeCoins2 = runState threeCoins (mkStdGen 2)
-- rollDie and rollNDice are not explained in the book LYAHFGG.
-- But these functions are interesting and complementary:
rollDie :: State StdGen Int
rollDie =
get >>=
\generator ->
let (value, newGenerator) = randomR (1,6) generator
in
put newGenerator >>
return value
rollDie1 = runState rollDie (mkStdGen 1)
rollDie2 = runState rollDie (mkStdGen 2)
rollNDice :: Int -> State StdGen [Int]
rollNDice 0 = return []
rollNDice n =
rollDie >>=
\value -> rollNDice (n-1) >>=
\list -> return (value:list)
rollNDice1 = runState (rollNDice 10) (mkStdGen 1)
rollNDice2 = runState (rollNDice 20) (mkStdGen 2)