ghci> let x = 1 + 1 -- サンクが積まれる ghci> print x -- サンクが潰れて2になる ・逆に必要のない式は評価されず、サンクのまま ・cond = False なら expensive は一度も評価されない let x = expensive in if cond then x + x else 0 20 / 52
= {} def fib(n): if n in memo: # キャッシュを引く return memo[n] if n < 2: return n result = fib(n - 1) + fib(n - 2) memo[n] = result # return result キャッシュに入れる 33 / 52
class Functor f where fmap :: (a -> b) -> f a -> f b fmap (+1) [1, 2, 3] -- [2,3,4] fmap (+1) (Right 2) -- Right 3 fmap (+1) (Left "error") -- Left "error" 38 / 52
UserId -> Response handle uid = case greeting uid of Right msg -> ok 200 msg Left (NotFound _) -> err 404 "user not found" Left (DbDown detail) -> err 500 detail ・ fmap は Right (成功)のときだけ中身に関数適用し、 Left (失敗)は素通り ・ユーザにエラーメッセージを返すまで失敗の取り出しを遅延できる 43 / 52
fmap でつなぐことで、型の文脈を壊さずに関数合成ができる ・例外ではなく、失敗情報 or 成功結果のどちらかを持つ Either を使って失敗 情報を扱う Very Elegant!! (今回は失敗するかもしれない処理は1つだったが、複数扱う場合にはMonadや Applicativeを使う) 44 / 52
Pure Functions, Laziness, I/O, and Monads - School of Haskell(Bartosz Milewski、2014) ・ 関数型プログラミング - Wikipedia ・ A History of Haskell: Being Lazy with Class(Paul Hudak / John Hughes / Simon Peyton Jones / Philip Wadler、HOPL III, 2007) ・ Why Functional Programming Matters(John Hughes、1990) ・ Beating the Averages(Paul Graham) ・ 単体テストの考え方/使い方(Vladimir Khorikov、須田智之 訳、マイナビ出版) ・ 関数型ドメインモデリング(Scott Wlaschin、猪股健太郎 訳、アスキードワンゴ) 46 / 52