do記法
do記法は純粋関数の世界で手続き型っぽく記述できるもの
do式はそれ全体が式
実行ステップは1つ1つがアクション
code:hs
main = do
v1 <- a1 -- ←これはアクション
v2 <- a2 -- ←これも
return $ v1 + v2
最後の行はdo式全体の結果になる
型のイメージ
code:hs
main = 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
code:haskell
m >>= f >>= g
code:haskell
do x <- m -- アクションmの結果をxに束縛. アクションから値を取り出す
y <- f x -- xにアクションfを適用した結果をyに束縛
g y -- yにアクションgを適用
doブロックの各行はbindで結ばれている
code:hs
main = do
print "hello"
print "world"
main = -- 上と同じ
print "hello" >>= \_ ->
print "world"
わかりやすいmrsekut.icon
code:doあり.hs
hoge x = do
foo <- m
bar <- mFunction x
m''
return $ foo + bar
code:doなし.hs
hoge x = (
m >>= (\foo ->
mFunction x >>= (\bar ->
m'' >>= (\_ ->
return $ foo + bar
))))
do記法やbindを使うことでパターンマッチよりもきれいに書ける
すごいH本.icon p.295より以下のコードを引用
パターンマッチを使った場合
code:hs
routine :: 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を使った場合
code:hs
routine :: Maybe (Int, Int)
routine = landLeft 1 (0, 0) >>= landRight 4 >>= landLeft 2 >>= landLeft 1
do記法を用いた場合
code:hs
routine :: Maybe (Int, Int)
routine = do
pole1 <- landLeft 1 (0, 0)
pole2 <- landRight 4 pole1
pole3 <- landLeft 2 pole2
landLeft 1 pole3
参考
doについて。わかりやすい