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

モナドがくれたもの

Sponsored · SiteGround - Reliable hosting with speed, security, and support you can count on.

 モナドがくれたもの

Avatar for Tomohiko Himura

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 イメージです。