Haskell语言学习笔记(13)Monadic Functions

来源:互联网 发布:数据段 代码段堆栈段 编辑:程序博客网 时间:2024/05/20 00:37

Monadic Functions

liftM

Monad 的 liftM 相当于 Functor 的 fmap。
liftM :: (Monad m) => (a1 -> r) -> m a1 -> m rliftM f m1 = do { x1 <- m1; return (f x1) }
Prelude Control.Monad> liftM (*3) (Just 8)Just 24Prelude Control.Monad> liftM (*3) [1,2,3][3,6,9]Prelude Control.Monad> putStr "Write your string: " >> liftM (map Data.Char.toUpper) getLine >>= putStrLnWrite your string: This is my string!THIS IS MY STRING!

ap

Monad 的 ap 相当于 Applicative Functor 的 <*>。
ap :: (Monad m) => m (a -> b) -> m a -> m bap m1 m2 = do { x1 <- m1; x2 <- m2; return (x1 x2) }
Prelude Control.Monad> ap (Just (*3)) (Just 8)Just 24Prelude Control.Monad> ap [(*3),(+3)] [1,2,3][3,6,9,4,5,6]

liftM2 liftM3 liftM4 liftM5

Monad 的 liftM2 相当于 Applicative Functor 的 liftA2。
liftM2 :: (Monad m) => (a1 -> a2 -> r) -> m a1 -> m a2 -> m rliftM2 f m1 m2 = do { x1 <- m1; x2 <- m2; return (f x1 x2) }liftM3 :: (Monad m) => (a1 -> a2 -> a3 -> r) -> m a1 -> m a2 -> m a3 -> m rliftM3 f m1 m2 m3 = do { x1 <- m1; x2 <- m2; x3 <- m3; return (f x1 x2 x3) }
Prelude Control.Monad> liftM2 (*) (Just 3) (Just 8)Just 24Prelude Control.Monad> liftM2 (*) [1,2,3] [4,5,6][4,5,6,8,10,12,12,15,18]

join

join 函数移除一层 Monadic structure, 使其平坦化。
join :: (Monad m) => m (m a) -> m ajoin x = x >>= id
Prelude Control.Monad> join (Just (Just 9))Just 9Prelude Control.Monad> join [[1,2,3],[4,5,6]][1,2,3,4,5,6]

filterM

filterM 是列表操作函数 filter 的一般化。
filterM :: (Applicative m) => (a -> m Bool) -> [a] -> m [a]
import Control.Monadimport Control.Monad.Trans.WriterkeepSmall :: Int -> Writer [String] BoolkeepSmall x    | x < 4 = do        tell ["Keeping " ++ show x]        return True    | otherwise = do        tell [show x ++ " is too large, throwing it away"]        return Falsemain = do    let (a, w) = runWriter $ filterM keepSmall [9,1,5,2,10,3]    mapM_ putStrLn w; print a{-9 is too large, throwing it awayKeeping 15 is too large, throwing it awayKeeping 210 is too large, throwing it awayKeeping 3[1,2,3]-}
Prelude Control.Monad> filterM (\x -> [False, True]) [1,2,3][[],[3],[2],[2,3],[1],[1,3],[1,2],[1,2,3]]

foldM

foldM 是列表操作函数 foldl 的一般化。
foldM :: (Foldable t, Monad m) => (b -> a -> m b) -> b -> t a -> m b
Prelude Control.Monad> let binSmalls acc x = if x > 9 then Nothing else Just (acc + x)Prelude Control.Monad> foldM binSmalls 0 [2,8,3,1]Just 14Prelude Control.Monad> foldM binSmalls 0 [2,11,3,1]Nothing

replicateM replicateM_

replicate 函数所对应的 monadic 版本。
replicateM        :: (Applicative m) => Int -> m a -> m [a]replicateM cnt0 f =    loop cnt0  where    loop cnt        | cnt <= 0  = pure []        | otherwise = liftA2 (:) f (loop (cnt - 1))
Prelude Control.Monad> replicateM 3 getLine123["1","2","3"]

when unless

when函数:给定一个布尔值和一个IO Action,如果布尔值为真,就执行IO Action,否则返回空。
when :: (Applicative f) => Bool -> f () -> f ()when p s  = if p then s else pure ()unless :: (Applicative f) => Bool -> f () -> f ()unless p s = if p then pure () else s
                                             
0 0
原创粉丝点击