関数モナド
((->) r)のモナド
r 型の値を適用して初めて、結果が取り出せるような文脈
実装
code:hs
instance Monad ((->) r) where
return = const
h >>= f = \w -> f (h w) w
constは2引数を取って2つ目を無視する関数
const :: a -> b -> a
bindの返り値はモナドなので
bindは「関数」を返す
(>>=) :: m a -> (a -> m b) -> m b
hは関数
fは関数を返す関数
>>=を用いた例
code:hs
h = (+2)
f x = (*x)
-- (>>=) h f は関数
(>>=) h f 10 -- 120 (= (10 + 2) * 10)
do式を用いた例
code:hs
-- kは普通の関数
k :: Int -> Int
k = do -- k 3を実行したときの例
a <- (* 2) -- a = 3*2 = 6
b <- (+ 10) -- b = 3+10 = 13
return $ a * b -- 13*6 = 78
具体例 ref 『関数プログラミング実践入門』.icon p.255
code:hs
countOdd :: ((->) Int) Int -- Int -> Int と同じ countOdd = length . filter odd
countEven :: ((->) Int) Int countEven = length . filter even
countAll :: ((->) Int) Int countAll xs = countOdd xs + countEven xs
これらの関数は((->) [Int]) aという型を持ち回しているように見ることが出来る
文脈を持っている
こう書き直せる
code:hs
countAll = do
odds <- countOdd
evens <- countEven
return $ odds + evens