LoginSignup
7
1

More than 5 years have passed since last update.

リストモナドのdo記法

Posted at

do記法を使って次のように書くことができて,不思議だと思った.

test = do
    a <- [1,2]
    b <- [3,4]
    [(a,b)]

main = print test
実行結果
[(1,3),(1,4),(2,3),(2,4)]

どういうことなのか,自分なりに納得したいと思ったので,調べた.以降,次のコードの動きを説明する.

test = do
    [1,2]
    [3,4]

main = print test
実行結果
[3,4,3,4]

do記法のルール

Haskll 2010 Language Reportの3.14によると,eが式のときは次の決まりになっている.

  • do {e}eになる
  • do {e;stmts}e >> do {stmts}になる

以上の決まりによりtestは次のものと同じ

test = [1,2] >> [3,4]

モナドの>>演算子

ライブラリの説明によると,>>は次のように定義されている.

class Applicative m => Monad m where
    (>>) :: m a -> m b -> m b
    m >> k = m >>= \_ -> k

mの値を文脈と呼ぶことにすると,>>は文脈を捨てる感じ.モナドは>>=(bind)とreturnしかないので,>>では>>=を使って文脈を捨てる必要があった.

この定義を使うとtestは次のようになる.

test = [1,2] >>= \_ -> [3,4]

リストモナドの>>=

ライブラリの説明によると,リストの>>=の定義は次の通り.

instance Monad []  where
    xs >>= f = [y | x <- xs, y <- f x]

この文法はList comprehensionで,Haskll 2010 Language Reportの3.11で解説されている.

この定義を使うとtestは次のようになる.

test = [y | x <- [1,2], y <- [3,4]]

以上でtest[3,4,3,4]になる.

7
1
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
7
1