Haskell超初心者勉強会20

565 views

Published on

Published in: Technology, News & Politics
0 Comments
0 Likes
Statistics
Notes
  • Be the first to comment

  • Be the first to like this

No Downloads
Views
Total views
565
On SlideShare
0
From Embeds
0
Number of Embeds
2
Actions
Shares
0
Downloads
5
Comments
0
Likes
0
Embeds 0
No embeds

No notes for slide

Haskell超初心者勉強会20

  1. 1. Haskell超初心者勉強会20 第14章 後半 2013/9/9 Sunday, September 8, 13
  2. 2. 今日の内容 •Maybe モナドで電卓を安全にする •モナディック関数の合成 •新しいモナドを作る Sunday, September 8, 13
  3. 3. これまでの電卓 •方針: Maybe を使って、失敗を正しく扱う solveRPN :: String -> Double solveRPN = head . foldl foldingFunction [] . words foldingFunction :: [Double] -> String -> [Double] foldingFunction (x:y:ys) "*" = (y * x):ys foldingFunction (x:y:ys) "+" = (y + x):ys foldingFunction (x:y:ys) "-" = (y - x):ys foldingFunction xs numberString = read numberString:xs キケン!! http://ideone.com/FNWy4l Sunday, September 8, 13
  4. 4. reads (用意されている) •読み取りに成功した時、[(読み取り結 果, 消費しきれなかった文字列)] •読み込み失敗時は空リスト > reads "123" :: [(Double, String)] [(123.0,"")] > reads "123abc" :: [(Double, String)] [(123.0,"abc")] > reads "abc" :: [(Double, String)] [] Sunday, September 8, 13
  5. 5. readMaybe •全部読めたら Just •それ以外は Nothing readMaybe :: (Read a) => String -> Maybe a readMaybe st = case reads st of [(x, "")] -> Just x _ -> Nothing Sunday, September 8, 13
  6. 6. 畳み込み関数 •Maybe [Double] を返すモナディック 関数に変更する foldingFunction :: [Double] -> String -> Maybe [Double] foldingFunction (x:y:ys) "*" = return $ (y * x):ys foldingFunction (x:y:ys) "+" = return $ (y + x):ys foldingFunction (x:y:ys) "-" = return $ (y - x):ys foldingFunction xs numberString = liftM (:xs) (readMaybe numberString) Sunday, September 8, 13
  7. 7. 安全な solveRPN •bind するときに pattern match •pattern match に失敗すると Nothing solveRPN :: String -> Maybe Double solveRPN st = do [result] <- foldM foldingFunction [] (words st) return result http://ideone.com/BiVXC4 Sunday, September 8, 13
  8. 8. モナディック関数の合成 <=< -- ただの関数合成 . f = (+1) . (*100) -- モナディック関数の合成 <=< -- テキストでは型宣言が無いが、型宣言が無いとコンパイルエラーになる。 g :: (Monad m, Num a) => a -> m a g = (x -> return (x + 1)) <=< (x -> return (x * 100)) Sunday, September 8, 13
  9. 9. . → >=> id → return -- これはただの関数合成 f' = foldr (.) id [(+8),(*100),(+1)] •ナイトが3手で行けるかを確認する関数 canReachIn3 を 関数合成でn手に一般化します。 •コード参照 http://ideone.com/l1GXEu Sunday, September 8, 13
  10. 10. モナドを作る •確率付きの値を表す Prob a •確率部は Rational で表す •1%2 → 1/2の確率 •[(3,1%2),(5,1%4),(9,1%4)] など Sunday, September 8, 13
  11. 11. Prob newtype宣言 newtype Prob a = Prob { getProb :: [(a, Rational)] } deriving Show Sunday, September 8, 13
  12. 12. Prob は Functor? •List が Functor だから Prob もきっと Functor •値に作用させる •確率はそのまま instance Functor Prob where fmap f (Prob xs) = Prob $ map ((x, p) -> (f x, p)) xs Sunday, September 8, 13
  13. 13. Prob は Monad? return •値がきたら、確率 1 の Prob にすれば いいのでは。 return x = Prob [(x, 1%1)] Sunday, September 8, 13
  14. 14. Prob は Monad? >=> • m >>= f は常に join (fmap f m) と等価 • join :: Prob (Prob a) -> Prob a から考えて、それを使って >>= を定義 Sunday, September 8, 13
  15. 15. flatten (join) •外側の確率と内側の確率を掛ける flatten :: Prob (Prob a) -> Prob a flatten (Prob xs) = Prob $ concat $ map multAll xs where multAll (Prob innerxs, p) = map ((x, r) -> (x, p*r)) innerxs Sunday, September 8, 13
  16. 16. Prod as Monad •モナド則を満たしていることを確認 instance Monad Prob where -- 文脈に入れるときは、必ずそれが起こる (=生起確率 1) で入れる。 return x = Prob [(x, 1%1)] -- m >>= f は join (fmap f m) m >>= f = flatten (fmap f m) -- パターンマッチに失敗したら fail _ = Prob [] Sunday, September 8, 13
  17. 17. イカサマコインを 投げる例 •コード参照 http://ideone.com/6FPW8M Sunday, September 8, 13
  18. 18. Monadが出来るまで •ある問題のある側面をモデル化した型 •あれ?もしや Monad?(気付き) •Monad instance を与える Sunday, September 8, 13
  19. 19. やっと14章おわったーー! Sunday, September 8, 13

×