15

モナドは、Haskell の型システムでは示されていませんが、理論的にはファンクターのサブセットであり、具体的には適用可能なファンクターであることが知られています。

モナドが与えられ、 と に基づいていることを知っているreturnbind、次のようになります。

  • 導出fmap
  • 派生<*>
4

2 に答える 2

26

つまり、モナドアクションの結果を純粋な関数で変換したいのですfmap(a -> b) -> f a -> f bこれは do 記法で簡単に書けます:

fmap f m = do
  a <- m
  return (f a)

または、「生」と書かれています:

fmap f m = m >>= \a -> return (f a)

これは として入手できますControl.Monad.liftM

pure :: a -> f aもちろんreturnです。(<*>) :: f (a -> b) -> f a -> f b少しトリッキーです。関数を返すアクションとその引数を返すアクションがあり、その結果を返すアクションが必要です。再び do 記法で:

mf <*> mx = do
  f <- mf
  x <- mx
  return (f x)

または、脱糖:

mf <*> mx =
  mf >>= \f ->
  mx >>= \x ->
  return (f x)

多田!これは として利用できるので、次のように任意のモナドに対してとControl.Monad.apの完全なインスタンスを与えることができます:FunctorApplicativeM

instance Functor M where
  fmap = liftM

instance Applicative M where
  pure = return
  (<*>) = ap

理想的には、この提案Monadのように、モナドごとに個別のインスタンスを定義する負担を軽減するために、これらの実装を で直接指定できます。そうなった場合、のスーパークラスを作成するのに実質的な障害はありません。既存のコードを壊さないことが保証されるからです。一方、これは、特定のインスタンスの定義に関与するボイラープレートが最小限であることを意味するため、「善良な市民」になるのは簡単です (そして、そのようなインスタンスはモナドに対して定義する必要があります)。ApplicativeMonadFunctorApplicativeMonad

于 2012-02-01T15:22:13.070 に答える
10

fmap = liftM(<*>) = apliftMapのソース コードへのリンクは次のとおりです。do表記を脱糖する方法を知っていると思います。

于 2012-02-01T15:17:50.503 に答える