モナド(Haskell)
code:monad_cls.hs
class Monad m where
(>>=) :: m a -> (a -> m b) -> m b
return :: a -> m a
code:monad.hs
(return x) >>= f == f x
m >>= return == m
(m >>= f) >>= g == m >>= (\x -> f x >>= g)
code:maybe.hs
data Maybe a = Nothing | Just a deriving (Eq, Ord)
code:lookup.hs
lookup :: (Eq a) => a -> (a, b) -> Maybe b code:usage_lookup.hs
lookup key (x,y)でx == keyになる最初のタプルのyをJust yとしてまたは無かった場合はNothingを返却
こういったものを考える
code:config.hs
config =
[ ( "database",
[ ("path", "/var/app/db"),
("encoding", "utf-8")
]
),
( "urlmapper",
[ ("path", "/app"),
("rewrite", "True")
]
),
( "template",
[ ("path", "/var/app/template")
]
)
]
いま これからdatabase.encodingを探すぞ〜
code:config_lookup.hs
encoding = case lookup "database" config of
Just entries -> lookup "encoding" entries
Nothing -> Nothing
code:config_maybemonad.hs
lookup "database" config >>= lookup "encoding"
code:implement_maybemonad.hs
instance Monad Maybe where
(Just x) >>= f = f x
Nothing >>= f = Nothing
return x = Just x
今 lookup "database" configの値がJust [("path", "/var/app/db"), ("encoding", "utf-8")]なので
Just [("path", "/var/app/db"), ("encoding", "utf-8")] >>= lookup
lookup "encoding" [("path", "/var/app/db"), ("encoding", "utf-8")]となる
強引にreturnを使うとすると
return config >>= lookup "database" >>= lookup "encoding"
(Just config) >>= lookup "database" >>= lookup "encoding
lookup "database" config >>= lookup "encoding"
関数expandCharClassと関数expandAltWordsがあって次のように
code:expander.hs
この関数をガッチャンコしてexpandPatternを書くぞ〜
code:expandPattern.hs
expandPattern :: String -> String expandPattern pattern = expandCharClass pattern >>= expandAltWords
expandPattern pattern = return pattern >>= expandCharClass >>= expandAltWords -- alt
code:usage_expandPattern.hs
code:impl_listmonad.hs
instance Monad [] where
xs >>= f = concatMap f xs
concatMap f xsとconcat $ map f xsが等価
code:concat.hs
code:concat_usage.hs
expandPattern "img[012].{jpg,png}
return "img[012].{jpg,png}" >>= expandCharClass >>= expandAltWords
["img[012].{jpg,png}"] >>= expandCharClass >>= expandAltWords
concatMap expandCharClass ["img[012].{jpg,png}"] >>= expandAltWords
["img0.{jpg,png}", "img1.{jpg,png}", "img2.{jpg,png}"] >>= expandAltWords
concatMap expandAltWords ["img0.{jpg,png}", "img1.{jpg,png}", "img2.{jpg,png}"]
["img0.png", "img1.png", "img2.png", "img0.jpg", "img1.jpg", "img2.jpg"]