Upgrade to Pro — share decks privately, control downloads, hide ads and more …

モナドがくれたもの

 モナドがくれたもの

Tomohiko Himura

September 05, 2015
Tweet

More Decks by Tomohiko Himura

Other Decks in Programming

Transcript

  1. ม਺aͷ஋͸Կ? import Data.Map as M hiding (map, foldr) table =

    M.fromList [("a",2), ("b",3), (“c",4)] lookupA :: Maybe Int lookupA = M.lookup "a" table -- => Just 2
  2. ม਺aͷ஋͸Կ? import Data.Map as M hiding (map, foldr) table =

    M.fromList [("a",2), ("b",3), (“c",4)] lookupA :: Maybe Int lookupA = M.lookup "a" table -- => Just 2 Just is 何?
  3. ม਺zͷ஋͸ʁ table = M.fromList [("a",2), ("b",3), (“c",4)] lookupZ :: Maybe

    Int lookupZ = M.lookup "z" table -- => Nothing 変数z はないよ
  4. ͳΕͯΔߟ͑ํͰ -- a ͸औΕͳ͍͔΋͠Εͳ͍ͷͰ͜ΕΛߟྀ͢Δ aPlus1 :: Maybe Int aPlus1 =

    let a = M.lookup "a" table in if isJust a then Just (1 + (fromJust a)) else Nothing aPlus1 -- => Just 3
  5. ͳΕͯΔߟ͑ํͰ -- a ͸औΕͳ͍͔΋͠Εͳ͍ͷͰ͜ΕΛߟྀ͢Δ aPlus1 :: Maybe Int aPlus1 =

    let a = M.lookup "a" table in if isJust a then Just (1 + (fromJust a)) else Nothing aPlus1 -- => Just 3 a が Justか確認
  6. ͳΕͯΔߟ͑ํͰ -- a ͸औΕͳ͍͔΋͠Εͳ͍ͷͰ͜ΕΛߟྀ͢Δ aPlus1 :: Maybe Int aPlus1 =

    let a = M.lookup "a" table in if isJust a then Just (1 + (fromJust a)) else Nothing aPlus1 -- => Just 3 a が Justか確認 Just をはずして1を足す
  7. ͳΕͯΔߟ͑ํͰ -- a ͸औΕͳ͍͔΋͠Εͳ͍ͷͰ͜ΕΛߟྀ͢Δ aPlus1 :: Maybe Int aPlus1 =

    let a = M.lookup "a" table in if isJust a then Just (1 + (fromJust a)) else Nothing aPlus1 -- => Just 3 a が Justか確認 Just をはずして1を足す a がなかった場合と区別するために Justをつける
  8. ύλʔϯϚονΛ͔ͭͬͨॻ͖ํ aPlus1' :: Maybe Int aPlus1' = case M.lookup "a"

    table of Nothing -> Nothing Just a -> Just (a + 1) 変数aがなかったら Nothing
  9. ύλʔϯϚονΛ͔ͭͬͨॻ͖ํ aPlus1' :: Maybe Int aPlus1' = case M.lookup "a"

    table of Nothing -> Nothing Just a -> Just (a + 1) 変数aがなかったら Nothing 変数aがあったら aと名付ける
  10. ύλʔϯϚονΛ͔ͭͬͨॻ͖ํ aPlus1' :: Maybe Int aPlus1' = case M.lookup "a"

    table of Nothing -> Nothing Just a -> Just (a + 1) 変数aがなかったら Nothing 変数aがあったら aと名付ける aに1を足してJustにする
  11. fmap aPlus1'' = fmap (\a -> a + 1) (M.lookup

    "a" table) aPlus1’’ -- => Just 3
  12. fmap aPlus1'' = fmap (\a -> a + 1) (M.lookup

    "a" table) aPlus1’’ -- => Just 3 変数aがあったら a + 1をする
  13. fmap aPlus1'' = fmap (\a -> a + 1) (M.lookup

    "a" table) aPlus1’’ -- => Just 3 変数aがあったら a + 1をする JustやNothingはでてこない (結果には出る)
  14. fmap aPlus1'' = fmap (\a -> a + 1) (M.lookup

    "a" table) aPlus1’’ -- => Just 3 変数aがあったら a + 1をする JustやNothingはでてこない (結果には出る) a + 1 が興味の中心
  15. a + b aPlusB :: Maybe Int aPlusB = case

    M.lookup "a" table of Nothing -> Nothing Just a -> case M.lookup "b" table of Nothing -> Nothing Just b -> Just (a + b) -- Just
  16. a + b aPlusB :: Maybe Int aPlusB = case

    M.lookup "a" table of Nothing -> Nothing Just a -> case M.lookup "b" table of Nothing -> Nothing Just b -> Just (a + b) -- Just Just と Nothingの確認をひたすら…
  17. ந৅Խ…ʁ -- ந৅Խ? Just (Just 5) ͭΒ͍… aPlusB' :: Maybe

    (Maybe Int) aPlusB' = fmap (\a -> fmap (\b -> a + b ) (M.lookup "b" table) ) (M.lookup "a" table) aPlusB’ -- => Just (Just 5)
  18. joinΛಋೖ aPlusB'' :: Maybe Int aPlusB'' = join . fmap

    (\a -> fmap (\b -> a + b ) (M.lookup "b" table) ) $ (M.lookup "a" table)
  19. a + b + c aPlusBPlusC :: Maybe Int aPlusBPlusC

    = case M.lookup "a" table of Nothing -> Nothing Just a -> case M.lookup "b" table of Nothing -> Nothing Just b -> case M.lookup "c" table of Nothing -> Nothing Just c -> Just $ a + b + c
  20. a + b + c aPlusBPlusC :: Maybe Int aPlusBPlusC

    = case M.lookup "a" table of Nothing -> Nothing Just a -> case M.lookup "b" table of Nothing -> Nothing Just b -> case M.lookup "c" table of Nothing -> Nothing Just c -> Just $ a + b + c Just と Nothingの確認をひたすら…
  21. ந৅Խ aPlusBPlusC' :: Maybe (Maybe (Maybe Int)) aPlusBPlusC' = fmap

    (\a -> fmap (\b -> fmap (\c -> a + b + c ) (M.lookup "c" table) ) (M.lookup "b" table) ) (M.lookup "a" table) aPlusBPlusC' -- Just (Just (Just 9))
  22. ந৅Խ aPlusBPlusC' :: Maybe (Maybe (Maybe Int)) aPlusBPlusC' = fmap

    (\a -> fmap (\b -> fmap (\c -> a + b + c ) (M.lookup "c" table) ) (M.lookup "b" table) ) (M.lookup "a" table) aPlusBPlusC' -- Just (Just (Just 9)) 綺麗な形をしているけど Just (Just (Just 9)) がつらい
  23. joinͷಋೖ aPlusBPlusC_' :: Maybe Int aPlusBPlusC_' = join . fmap

    (\a -> join . fmap (\b -> fmap (\c -> a + b + c ) (M.lookup "c" table) ) $ (M.lookup "b" table) ) $ (M.lookup "a" table)
  24. joinͷಋೖ aPlusBPlusC_' :: Maybe Int aPlusBPlusC_' = join . fmap

    (\a -> join . fmap (\b -> fmap (\c -> a + b + c ) (M.lookup "c" table) ) $ (M.lookup "b" table) ) $ (M.lookup "a" table) Just 9 になったけど 最深部だけ違う…おしい
  25. ͘Γ͔͑ͨ͢Ίʹগ͠৑௕ʹ aPlusBPlusC'' :: Maybe Int aPlusBPlusC'' = join . fmap

    (\a -> join . fmap (\b -> join . fmap (\c -> Just $ a + b + c ) $ (M.lookup "c" table) ) $ (M.lookup "b" table) ) $ (M.lookup "a" table)
  26. ͘Γ͔͑ͨ͢Ίʹগ͠৑௕ʹ aPlusBPlusC'' :: Maybe Int aPlusBPlusC'' = join . fmap

    (\a -> join . fmap (\b -> join . fmap (\c -> Just $ a + b + c ) $ (M.lookup "c" table) ) $ (M.lookup "b" table) ) $ (M.lookup "a" table) くりかえし同じことをしている
  27. ந৅Խ aPlusBPlusC''' :: Maybe Int aPlusBPlusC''' = (>>= (\a ->

    (>>= (\b -> (>>= (\c -> return $ a + b + c )) (M.lookup "c" table) )) (M.lookup "b" table) )) (M.lookup "a" table)
  28. ੔ཧ͢Δ aPlusBPlusC'''' :: Maybe Int aPlusBPlusC'''' = M.lookup "a" table

    >>= \a -> M.lookup "b" table >>= \b -> M.lookup "c" table >>= \c -> return $ a + b + c
  29. do ߏจΛ࢖͏ aPlusBPlusC''''' :: Maybe Int aPlusBPlusC''''' = do a

    <- M.lookup "a" table b <- M.lookup "b" table c <- M.lookup "c" table return $ a + b + c
  30. ݩͷͱൺֱ aPlusBPlusC :: Maybe Int aPlusBPlusC = case M.lookup "a"

    table of Nothing -> Nothing Just a -> case M.lookup "b" table of Nothing -> Nothing Just b -> case M.lookup "c" table of Nothing -> Nothing Just c -> Just $ a + b + c
  31. ͔ͭͬͯΈΔ aPlusBPlusC_ (M.lookup "a" table) (M.lookup "b" table) (M.lookup "c"

    table) — Just 9 aPlusBPlusC_ (Just 2) (Just 3) (Just 4) — Just 9 aPlusBPlusC_ Nothing (Just 3) (Just 4) — Nothing aPlusBPlusC_ (Just 2) Nothing (Just 4) — Nothing
  32. ந৅Խ͍ͯ͠ΔͷͰϦετͰ΋ aPlusBPlusC_ [2] [3] [4] — [9] aPlusBPlusC_ [] [3]

    [4] — [] aPlusBPlusC_ [2] [] [4] — [] aPlusBPlusC_ [2,3] [3] [4] — [9,10] aPlusBPlusC_ [2,3] [3,4] [4] — [9,10,10,11]
  33. ந৅Խ͍ͯ͠ΔͷͰϦετͰ΋ aPlusBPlusC_ [2] [3] [4] — [9] aPlusBPlusC_ [] [3]

    [4] — [] aPlusBPlusC_ [2] [] [4] — [] aPlusBPlusC_ [2,3] [3] [4] — [9,10] aPlusBPlusC_ [2,3] [3,4] [4] — [9,10,10,11] [2+3+4, 2+4+4, 3+3+4, 3+4+4]
  34. OOPͬΆ͘ omap = flip fmap listAPlusBPlusC :: [] ([] ([]

    Int)) listAPlusBPlusC = [2,3] `omap` \a -> [3,4] `omap` \b -> [4,5] `omap` \c -> a + b + c
  35. [] Int ͕͍͍ͳ͊ listAPlusBPlusC' :: [Int] listAPlusBPlusC' = [2,3] >>=

    \a -> [3,4] >>= \b -> [4] >>= \c -> return $ a + b + c
  36. do ߏจͰɻ listAPlusBPlusC'' = do a <- [2,3] b <-

    [3,4] c <- [4,5] return $ a + b + c
  37. >>= ͷத਎ Ϧετ൛ mA >>= f = case mA of

    [] -> [] x:xs -> go (f x) (xs >>= f) where go [] acc = acc go (y:ys) acc = y : (go ys acc)
  38. ՝୊༻ aPlusBPlusC_ mA mB mC = do mA >>= \a

    -> mB >>= \b -> mC >>= \c -> return $ a + b + c
  39. Maybe aPlusBPlusC__ mA mB mC = case mA of Nothing

    -> Nothing Just a -> case mB of Nothing -> Nothing Just b -> case mC of Nothing -> Nothing Just c -> Just (a + b + c)
  40. case mA of [] -> [] xa:xas -> go ((\a

    -> case mB of [] -> [] xb:xbs -> go ((\b -> case mC of [] -> [] x:xs -> go ((\c -> a + b + c) x) (xs >>= (\c -> a + b + c)) where go [] acc = acc go (y:ys) acc = y : (go ys acc) ) xb) (xbs >>= (\b -> case mC of [] -> [] x:xs -> go ((\c -> a + b + c) x) (xs >>= (\c -> a + b + c)) where go [] acc = acc go (y:ys) acc = y : (go ys acc) )) where gob [] accb = accb gob (yb:ybs) accb = y : (go ybs accb) ) xa) (xas >>= (\a -> )) where go [] acca = acca
  41. case mA of [] -> [] xa:xas -> go ((\a

    -> case mB of [] -> [] xb:xbs -> go ((\b -> case mC of [] -> [] x:xs -> go ((\c -> a + b + c) x) (xs >>= (\c -> a + b + c)) where go [] acc = acc go (y:ys) acc = y : (go ys acc) ) xb) (xbs >>= (\b -> case mC of [] -> [] x:xs -> go ((\c -> a + b + c) x) (xs >>= (\c -> a + b + c)) where go [] acc = acc go (y:ys) acc = y : (go ys acc) )) where gob [] accb = accb gob (yb:ybs) accb = y : (go ybs accb) ) xa) (xas >>= (\a -> )) where go [] acca = acca イメージです。