do記法
do記法は純粋関数の世界で手続き型っぽく記述できるもの
do式はそれ全体が式
実行ステップは1つ1つがアクション
hsmain = do
v1 <- a1 -- ←これはアクション
v2 <- a2 -- ←これも
return $ v1 + v2
最後の行はdo式全体の結果になる
型のイメージ
hsmain = do
a1 <- m a -- `m a`から`a`を取り出して束縛
b1 <- m b
return $ a1 + b1 -- `m (a1+a2)`つまり、`m a`を返してる
Maybeかもしれないし、IOかもしれないし、
m a
の a
の方の型は異なっていても良い
do 記法は bind を使った以下のものの糖衣構文
elm,scalaのandThen
haskelldo x <- m -- アクションmの結果をxに束縛. アクションから値を取り出す
y <- f x -- xにアクションfを適用した結果をyに束縛
g y -- yにアクションgを適用
doブロックの各行はbindで結ばれている
hsmain = do
print "hello"
print "world"
main = -- 上と同じ
print "hello" >>= \_ ->
print "world"
わかりやすい

doあり.hshoge x = do
foo <- m
bar <- mFunction x
m''
return $ foo + bar
doなし.hshoge x = (
m >>= (\foo ->
mFunction x >>= (\bar ->
m'' >>= (\_ ->
return $ foo + bar
))))
do記法やbindを使うことでパターンマッチよりもきれいに書ける

p.295より以下のコードを引用
パターンマッチを使った場合
hsroutine :: Maybe (Int, Int)
routine = case landLeft 1 (0, 0) of
Nothing -> Nothing
Just pole1 -> case landRight 4 pole1 of
Nothing -> Nothing
Just pole2 -> case landLeft 2 pole2 of
Nothing -> Nothing
Just pole3 -> landLeft 1 pole3
bindを使った場合
hsroutine :: Maybe (Int, Int)
routine = landLeft 1 (0, 0) >>= landRight 4 >>= landLeft 2 >>= landLeft 1
do記法を用いた場合
hsroutine :: Maybe (Int, Int)
routine = do
pole1 <- landLeft 1 (0, 0)
pole2 <- landRight 4 pole1
pole3 <- landLeft 2 pole2
landLeft 1 pole3
参考
doについて。わかりやすい