liftM の使い方が分からなかったので調べてみました。
ghci> :m + Control.Monad ghci> :t liftM liftM :: (Monad m) => (a1 -> r) -> m a1 -> m r
liftM は
モナドの r を返す。
つまり、a1 を引数に r を帰す普通の関数をモナドにも適用出来るようにするもの、って理解で良いかな。
「liftM関連 - おっぱい大魔神の日記」の例が分かりやすい。
import Control.Monad str = return "Haskell"::Maybe String main = print $ liftM length str
length はリストを引数にリストの長さを返す関数ですから、以下のようにそのままではMaybe型の値に摘要出来ません。Nothing のときの場合分けとJust を外す操作が必要です。
length :: [a] -> Int
len = case str of Nothing -> Nothing Just s -> Just (length s)
liftM を使えばMaybe型のリストの長さを返し、リストが Nothing だったら、Nothing を返します。
> liftM length $ liftM (++".world!") $ Just "Hello" --=> Just 12 > liftM length $ liftM (++".world!") Nothing --=> Nothing > map (liftM length) [Nothing, Just "hello,world", Just ""] --=> [Nothing,Just 11,Just 0]
> len <- liftM length getLine :: IO Int Hello,world! > len --=> 12
Hoogle / liftM:lengthは引数がひとつですが、摘要する関数の引数に応じたliftMがあるようです。
- liftM のソース。
liftM のソースを見てみましょう。do 記法です。モナドm1からx1を取り出し、x1 に引数で受け取った関数 f を摘要し、 return でモナドにくるんで返しています。
-- | Promote a function to a monad. liftM :: (Monad m) => (a1 -> r) -> m a1 -> m r liftM f m1 = do { x1 <- m1; return (f x1) }