6. Hello, Haskell!
module Hello where
greeting :: String -> String
greeting name = “Hello, “ ++ name
main :: IO ()
main = do
putStrLn $ greeting “Haskell”
putStrLn “Nice to meet you!”
#ccc_l8
31. 最初に思いつく Haskell プログラム
type Stack = [Int]
pop :: Stack -> Int
pop (x : xs) = x
push :: Int -> Stack -> Stack
push x xs = x : xs
#ccc_l8
32. 最初に思いつく Haskell プログラム
type Stack = [Int]
pop :: Stack -> Int
pop (x : xs) = x
push :: Int -> Stack -> Stack
push x xs = x : xs
型に別名(シノニム)をつけられる
#ccc_l8
33. 最初に思いつく Haskell プログラム
type Stack = [Int]
pop :: Stack -> Int
pop (x : xs) = x
push :: Int -> Stack -> Stack
push x xs = x : xs
Int 型の連結リスト
#ccc_l8
34. 最初に思いつく Haskell プログラム
type Stack = [Int]
pop :: Stack -> Int
pop (x : xs) = x
push :: Int -> Stack -> Stack
push x xs = x : xs
”:” で連結リストの先頭と残りを連結
#ccc_l8
36. 変化後の状態も明示的に返す
type Action a = Stack -> (a, Stack)
pop :: Action Int
pop (x : xs) = (x, xs)
push :: Int -> Action ()
push x xs = ((), (x : xs))
#ccc_l8
37. 変化後の状態も明示的に返す
type Action a = Stack -> (a, Stack)
pop :: Action Int
pop (x : xs) = (x, xs)
push :: Int -> Action ()
push x xs = ((), (x : xs))
a 型の値を返すスタックの操作を表す型
#ccc_l8
38. 変化後の状態も明示的に返す
type Action a = Stack -> (a, Stack)
pop :: Action Int
pop (x : xs) = (x, xs)
push :: Int -> Action ()
push x xs = ((), (x : xs))
変化後のスタック
#ccc_l8
39. 変化後の状態も明示的に返す
type Action a = Stack -> (a, Stack)
pop :: Action Int
pop (x : xs) = (x, xs)
push :: Int -> Action ()
push x xs = ((), (x : xs))
Unit: Java の void 相当
#ccc_l8
40. 変化後の状態も明示的に返す
addTop2 :: Action ()
addTop2 stack =
let (x1, stack1) = pop stack
(x2, stack2) = pop stack1
in push (x1 + x2) stack2
スタックのトップ 2 個を加算
#ccc_l8
41. 変化後の状態も明示的に返す
addTop2 :: Action ()
addTop2 stack =
let (x1, stack1) = pop stack
(x2, stack2) = pop stack1
in push (x1 + x2) stack2
1 回目の操作の結果を保持
#ccc_l8
42. 変化後の状態も明示的に返す
addTop2 :: Action ()
addTop2 stack =
let (x1, stack1) = pop stack
(x2, stack2) = pop stack1
in push (x1 + x2) stack2
1 回目の結果に対して 2 回目の操作
#ccc_l8
43. 変化後の状態も明示的に返す
addTop2 :: Action ()
addTop2 stack =
let (x1, stack1) = pop stack
(x2, stack2) = pop stack1
in push (x1 + x2) stack2
2 回目の結果に対して 3 回目の操作
#ccc_l8
81. ST (State Transformer) モナド
▪ 破壊的更新を局所化
▫ 実際にメモリ上の値を書き換える
▪ ST s TypeName
▫ s は「観測不可能」な内部状態
▫ s は常に型変数で、具体化できない
▪ 純粋な値を取り出すことができる
▫ IO モナドでは値の取り出しは不可能
#ccc_l8
82. Mutable なクラス
data JBuilder =
native java.lang.StringBuilder where
native new :: String
-> ST s (Mutable s JBuilder)
native append :: Mutable s JBuilder
-> String
-> ST s (Mutable s JBuilder)
#ccc_l8
83. Mutable なクラス
data JBuilder =
native java.lang.StringBuilder where
native new :: String
-> ST s (Mutable s JBuilder)
native append :: Mutable s JBuilder
-> String
-> ST s (Mutable s JBuilder)
入出力なしなら native のみ
#ccc_l8
84. Mutable なクラス
data JBuilder =
native java.lang.StringBuilder where
native new :: String
-> ST s (Mutable s JBuilder)
native append :: Mutable s JBuilder
-> String
-> ST s (Mutable s JBuilder)
外部から「観測不可能」な内部状態
#ccc_l8
85. Mutable なクラス
data JBuilder =
native java.lang.StringBuilder where
native new :: String
-> ST s (Mutable s JBuilder)
native append :: Mutable s JBuilder
-> String
-> ST s (Mutable s JBuilder)
Mutable でラップ
#ccc_l8
86. Mutable なクラス
data JBuilder =
native java.lang.StringBuilder where
native new :: String
-> ST s (Mutable s JBuilder)
native append :: Mutable s JBuilder
-> String
-> ST s (Mutable s JBuilder)
戻り値は ST モナド
#ccc_l8
87. Mutable なクラス
greeting :: String -> ST s String
greeting name = do
sb <- JBuilder.new “Hello, ”
sb.append name
sb.toString
pureGreeting :: String -> String
pureGreeting name = (greeting name).run
#ccc_l8
88. Mutable なクラス
greeting :: String -> ST s String
greeting name = do
sb <- JBuilder.new “Hello, ”
sb.append name
sb.toString
pureGreeting :: String -> String
pureGreeting name = (greeting name).run
ST モナドとして使用
#ccc_l8
89. Mutable なクラス
greeting :: String -> ST s String
greeting name = do
sb <- JBuilder.new “Hello, ”
sb.append name
sb.toString
pureGreeting :: String -> String
pureGreeting name = (greeting name).run
run で純粋な値を取り出す
#ccc_l8
90. Mutable なクラス
greeting :: String -> ST s String
greeting name = do
sb <- JBuilder.new “Hello, ”
sb.append name
sb.toString
pureGreeting :: String -> String
pureGreeting name = (greeting name).run
外から見ると純粋な関数
#ccc_l8
124. CREDITS
Special thanks to all the people who made and released
these awesome resources for free:
▪ Presentation template by SlidesCarnival
▪ Photographs by Unsplash