Haskell リストモナド 超入門の解答例です。
リストの作成
【問1】return
を使って[1, 2, 3]
を作ってください。
main = do
print $ 1 : 2 : return 3
実行結果
[1,2,3]
型クラス制約
【問2】次に示す関数join
の型から仕様を推定して、コードで検証してください。
二重にネストしたモナドを一重にします。
import Control.Monad
main = print $ join [[1, 2], [3]]
実行結果
[1,2,3]
ループ
【問3】次のコードをjoin
とforM
で書き替えてください。
import Control.Monad
main = do
print $ join $ join $
forM [1..3] $ \x ->
forM "abc" $ \y ->
return (x, y)
実行結果
[(1,'a'),(1,'b'),(1,'c'),(2,'a'),(2,'b'),(2,'c'),(3,'a'),(3,'b'),(3,'c')]
再実装
【問4】リストモナドを扱うbind
とreturn'
を実装してください。bind
にはfoldr
を使ってください。
bind xs f = foldr ((++) . f) [] xs
return' x = [x]
main = do
print $ [1..3] `bind` \x -> "abc" `bind` \y -> return' (x, y)
実行結果
[(1,'a'),(1,'b'),(1,'c'),(2,'a'),(2,'b'),(2,'c'),(3,'a'),(3,'b'),(3,'c')]
リスト内包表記
書き換え
【問5】次のリスト内包表記をdo
で書き換えてください。
main = do
print $ do
x <- [1..5]
y <- [1..5]
if x + y == 6
then return (x, y)
else []
実行結果
[(1,5),(2,4),(3,3),(4,2),(5,1)]
テスト
【問6】問5のコードを問4で実装したbind
とreturn'
に対応させてテストしてください。
bind xs f = foldr ((++) . f) [] xs
return' x = [x]
main = do
print $ do
[1..5] `bind` \x -> [1..5] `bind` \y ->
if x + y == 6 then return' (x, y) else []
実行結果
[(1,5),(2,4),(3,3),(4,2),(5,1)]