2012-02-01 7 views
15

モナスは、理論的には、それがHaskellの型システムには示されていないにもかかわらず、理論的にはファンクタのサブセットであり、具体的には適用可能なファンクタであることが知られている。どのように、モナド与えられた、ことを知り、returnbindに基づかモナドがファンクタと応用ファンクタであることを示すには?

  • fmapを導出

    • <*>を導き出しますか?
  • 答えて

    26

    まあ、はちょうど(a -> b) -> f a -> f bです。つまり、モナディックアクションの結果を純粋な関数で変換したいと考えています。これはControl.Monad.liftMとして利用可能である

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

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

    または、 "生" 書かれた:それはやる記法で書くのは簡単です。

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

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

    または、脱糖:

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

    多田!これはControl.Monad.apとして利用可能であるので、次のように我々はすべてのモナドMためFunctorApplicativeの完全なインスタンスを与えることができます:理想的

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

    を、私たちは、負担を軽減するために、Monadに直接これらの実装を指定することができるだろうthis proposalなど、すべてのモナドに個別のインスタンスを定義することができます。その場合、ApplicativeのスーパークラスをMonadというスーパークラスにすることには実質的な障害はありません。既存のコードを破らないようにするためです。一方、これは、与えられたMonadFunctorApplicativeのインスタンスを定義するのに必要な定型文は最小限であるため、「良い市民」(そしてそのようなインスタンスはどのモナドに対しても定義する必要があります)になりやすいことを意味します。

    +5

    与えられた 'Monad'インスタンス' m'が実際にMonadの法則を満たしているとすれば、あなたが 'fmap'、' pure'と '(<*>)'に提供するモナドの定義は、 FunctorおよびApplicativeの法律に従います。 Haskellが強制するのは、型チェックだけです。 –

    10

    fmap = liftMおよび(<*>) = ap。以下はliftMapのソースコードへのリンクです。私は表記をするdesugarする方法を知っていると仮定します。

    関連する問題