4. ●Haskellで手続き的に書くなんて邪道ではないか?
●Haskellの設計者 Simon Peyton Jones の言
●Tackling the Awkward Squad: monadic input/output, concurrency, exceptions, and foreign-language calls in Haskell
●Haskell is the world’s finest imperative programming language 「Haskellは世界最高の手続き型プログラミング言語です」
●設計者が手続き型言語と言っているので手続き的に書いて全く問題あ りません
Haskellに関するよくある誤解
14. ●関数合成
●関数合成もかなり多用される
●ポイントフリースタイル
●x -> f (g (h x)) は f . g . h と同じ
●例: filter (not . even) [1, 2, 3]
●'.' を使っているがメンバーやメソッドの参照ではない
Haskellコードの読み方 (続き)
Scala
Haskell
f compose g
f . g
15. ●関数合成の応用
●(.) : 関数合成の前置記法
●(.) f g は f . g と同じ
●(f .) : 関数合成の部分適用
Haskellコードの読み方 (続き)
19. ●モナドといってもdo記法の中では「文」を並べているように書けるの であまり違和感はない
●例:main :: IO () main = do let prompt = "Input your name: " let message = "Hello, " putStr prompt name <- getLine putStrLn $ message ++ name
●実際にはdo記法は >> と >>= を使った式に展開できる (cf. Real World Haskell 14.11)
Scala v.s. Haskell
21. ●繰り返しの例import Control.Monad -- forMを定義しているモジュール main :: IO () main = do let prompt = "Input your name: " let message = "Hello, " forM_ [1..5] $ i -> do putStr prompt name <- getLine putStrLn $ message ++ name
Scala v.s. Haskell
23. ●戻らない例 import Control.Monad main :: IO () main = do let prompt = "Input your name: " let message = "Hello, " forM_ [1..5] $ i -> do putStr prompt name <- getLine if name /= "" then do putStrLn $ message ++ name return () else putStrLn "Empty name is not allowed."
Scala v.s. Haskell
24. ●こういう時はどう書くか?
●再帰が一番無難な気がします loop :: IO () loop = do let prompt = "Input your name: " let message = "Hello, " putStr prompt name <- getLine if name /= "" then putStrLn $ message ++ name else do putStrLn "Empty name is not allowed." loop main :: IO () main = loop
Scala v.s. Haskell
25. ●対応表(変数)
●Haskellでも再代入できる
Scala v.s. Haskell
Scala
Haskell
val x = 1
x = 1
do記法の中では let x = 1
def fun = ...
fun = ...
var x = 1
varX <- newMVar 1
x = 2 (再代入)
modifyMVar_ varX (const $ return 2)
x (varの参照)
x <- readMVar varX