28. 例外例:チャットルームへ入る
28
readName = do
hPutStrLn handle "What is your name?"
name <- hGetLine handle
if null name
then readName
else mask $ restore -> do -- <1>
ok <- checkAddClient server name handle
case ok of
Nothing -> restore $ do -- <2>
hPrintf handle
"The name %s is in use, Choose anothern"
name
readName
Just client ->
restore (runClient server client) -- <3>
`finally` removeClient server name
29. readName = do
hPutStrLn handle "What is your name?"
name <- hGetLine handle
if null name
then readName
else mask $ restore -> do -- <1>
ok <- checkAddClient server name handle
case ok of
Nothing -> restore $ do -- <2>
hPrintf handle
"The name %s is in use, Choose anothern"
name
readName
Just client ->
restore (runClient server client) -- <3>
`finally` removeClient server name
チャットルームへ入る
例外例:チャットルームへ入る
29
30. 例外例:チャットルームへ入る
30
readName = do
hPutStrLn handle "What is your name?"
name <- hGetLine handle
if null name
then readName
else mask $ restore -> do -- <1>
ok <- checkAddClient server name handle
case ok of
Nothing -> restore $ do -- <2>
hPrintf handle
"The name %s is in use, Choose anothern"
name
readName
Just client ->
restore (runClient server client) -- <3>
`finally` removeClient server name
例外処理
31. readName = do
hPutStrLn handle "What is your name?"
name <- hGetLine handle
if null name
then readName
else mask $ restore -> do -- <1>
ok <- checkAddClient server name handle
case ok of
Nothing -> restore $ do -- <2>
hPrintf handle
"The name %s is in use, Choose anothern"
name
readName
Just client ->
restore (runClient server client) -- <3>
`finally` removeClient server name
入った後の処理
例外例:チャットルームへ入る
31
32. readName = do
hPutStrLn handle "What is your name?"
name <- hGetLine handle
if null name
then readName
else mask $ restore -> do -- <1>
ok <- checkAddClient server name handle
case ok of
Nothing -> restore $ do -- <2>
hPrintf handle
"The name %s is in use, Choose anothern"
name
readName
Just client ->
restore (runClient server client) -- <3>
`finally` removeClient server name
その後の処理が
全て付いてくる
例外例:チャットルームへ入る
32
41. readName = do
hPutStrLn handle "What is your name?"
name <- hGetLine handle
if null name
then readName
else mask $ restore -> do -- <1>
ok <- checkAddClient server name handle
case ok of
Nothing -> restore $ do -- <2>
hPrintf handle
"The name %s is in use, Choose anothern"
name
readName
Just client ->
restore (runClient server client) -- <3>
`finally` removeClient server name
その後の処理
その後の処理の高階関数化
41
42. readName' cont = do
hPutStrLn handle "What is your name?"
name <- hGetLine handle
if null name
then readName
else mask $ restore -> do -- <1>
ok <- checkAddClient server name handle
case ok of
Nothing -> restore $ do -- <2>
hPrintf handle
"The name %s is in use, Choose anothern"
name
readName
Just client ->
restore (cont server client) -- <3>
`finally` removeClient server name
その後の処理
その後の処理の高階関数化
42
引数で渡す
55. 代数的性質の嬉しさ
• みんな沢山知ってる代数的性質
• 交換則
• X * Y == Y * X
• 分配則
• X * (Y + Z) == X * Y + X * Z
• 結合則
• (X * Y) * Z == X * (Y * Z)
• 上記はどれも複数の構造を同一視して良い性質
• 複雑さと戦うための武器の一つ
55
59. 継続モナドのアクション
newtype Cont r a = Cont { runCont :: (a -> r) -> r }
type Cont' r a = (a -> r) -> r
• 関数を受け取って結果を返す関数、というアクション
• 引数の関数はアクションの最後で実行される
59
62. 62
newtype Cont r a = Cont { runCont :: (a -> r) -> r }
• 関数を受け取って結果を返す関数、というアクション
• 引数の関数はアクションの最後で実行される
継続モナドのアクション(再)
継続
継続
• 継続 =「その後に実行すること」が表現されている
継続
63. 継続モナドの定義
instance Monad (ContT r m) where
return x = ContT ($ x)
m >>= k =
ContT $ c -> runContT m (x -> runContT (k x) c)
63
64. 継続モナドの定義
instance Monad (ContT r m) where
return x = ContT ($ x)
m >>= k =
ContT $ c -> runContT m (x -> runContT (k x) c)
64
mを走らせる
mに渡す継続
65. 継続モナドの定義
instance Monad (ContT r m) where
return x = ContT ($ x)
m >>= k =
ContT $ c -> runContT m (x -> runContT (k x) c)
65
(k x)を走らせる
(k x)に渡す継続xはmが渡す
66. 継続モナドの定義
instance Monad (ContT r m) where
return x = ContT ($ x)
m >>= k =
ContT $ c -> runContT m (x -> runContT (k x) c)
66
全体の結果はアクションを返す
継続cは外からもらう
(k x)に渡す継続
67. 継続モナド例(trivial)
action1, action2, action3 :: Cont r Int
action1 = return 42
action2 = return 13
action3 = return 2
cont_ex = do
x <- action1
y <- action2
z <- action3
return (x + y + z)
67
action1の継続は
どれか?
68. 継続モナド例(trivial)
action1, action2, action3 :: Cont r Int
action1 = return 42
action2 = return 13
action3 = return 2
cont_ex = do
x <- action1
y <- action2
z <- action3
return (x + y + z)
68
action1の継続
(action1後に実行)
69. 69
action1, action2, action3 :: Cont r Int
action1 = return 42
action2 = return 13
action3 = return 2
cont_ex = do
x <- action1
y <- action2
z <- action3
return (x + y + z)
継続モナド例(trivial)
action2の継続
(action2後に実行)
70. 70
action1, action2, action3 :: Cont r Int
action1 = return 42
action2 = return 13
action3 = return 2
cont_ex = do
x <- action1
y <- action2
z <- action3
return (x + y + z)
継続モナド例(trivial)
action3の継続
(action3後に実行)
71. 71
cont_ex = do
x <- action1
y <- action2
z <- action3
return (x + y + z)
main = do
print $ runCont cont_ex id
継続モナド例(trivial)
最後に実行される
継続