replicate 3 "hi"
を生成します
["hi", "hi", "hi"]
しかし
liftM (replicate 3) "hi"
を生成します
["hhh", "iii"]
どのようにliftM動作しますか(正確に)?
この関数は*liftMの別名であり、リストを操作する場合と同じです。fmapmap
liftM (replicate 3) "hi"
= [replicate 3 x | x <- "hi"]
= [replicate 3 'h', replicate 3 'i']
= ["hhh", "iii"]
*liftMとの違いfmapは、クラスコンテキストが異なることです。これは、歴史的な理由により、をMonad意味するものではないためFunctorです。
要約:liftM = map。
liftM関数のタイプはMonad m => (a -> b) -> m a -> m bです。つまり、モナド内の関数と何かを受け取り、モナドを「介して」関数を適用します。(または、別の見方をすると、タイプがMonad m => (a -> b) -> (m a -> m b)あります。つまり、関数をモナドを介して動作する関数に変換します。)
この場合はliftM (replicate 3) ['h','i']("hi"個々の文字のリストの省略形であることに注意してください)、問題のモナドはリストモナドです。liftMforリストの定義は次のようになりますmap(2つの関数は同じタイプであり、これは大きなヒントです)。したがって、次のようになります。
liftM (replicate 3) ['h','i'] = map (replicate 3) ['h','i']
= [replicate 3 'h', replicate 3 'i'] = ["hhh","iii"]