Haskell IOモナド 超入門の解答例です。
シャッフル
【問1】次のコードからdo
を取り除いて、bindやreturn
は使わずにunIO
やIO
で書き換えてください。
{-# LANGUAGE UnboxedTuples #-}
import GHC.Base
import System.Random
shuffle [] = IO $ \s -> (# s, [] #)
shuffle xs = IO $ \s ->
let (# s1, n #) = unIO (getStdRandom $ randomR (0, length xs - 1) :: IO Int) s
(# s2, xs' #) = unIO (shuffle $ take n xs ++ drop (n + 1) xs) s1
in (# s2, (xs !! n) : xs' #)
main = IO $ \s ->
let (# s1, xs #) = unIO (shuffle [1..9]) s
(# s2, r #) = unIO (print xs) s1
in (# s2, r #)
実行結果(毎回異なる)
[3,5,4,9,2,7,8,6,1]
再実装
【問2】IOモナドを扱うbind
とreturn'
を実装してください。>>=
, <<=
, <-
, return
は使わないでください。
{-# LANGUAGE UnboxedTuples #-}
import GHC.Base
a `bind` b = IO $ \s ->
let (# s1, r1 #) = unIO a s
(# s2, r2 #) = unIO (b r1) s1
in (# s2, r2 #)
return' x = IO $ \s -> (# s, x #)
main = return' "hello" `bind` putStr `bind` print
実行結果
hello()