LoginSignup
1
2

More than 5 years have passed since last update.

【解答例】Haskell リストモナド 超入門

Last updated at Posted at 2014-12-18

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】次のコードをjoinforMで書き替えてください。

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】リストモナドを扱うbindreturn'を実装してください。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で実装したbindreturn'に対応させてテストしてください。

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)]
1
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
2