Help us understand the problem. What is going on with this article?

Haskell ArrowApplyからMonadを導出する

ArrowApplyはMonadと等価だという話を聞いたので、実際にArrowApplyからMonadを導出してみました。

標準ライブラリ中にはArrowMonadという型が定義されていますが、Arrow型の第一型引数が()に束縛されています。

ArrowMonad
newtype ArrowMonad a b = ArrowMonad (a () b)
forall a. Arrow a => instance Functor (ArrowMonad a)
forall a. Arrow a => instance Applicative (ArrowMonad a)
forall a. ArrowApply a => instance Monad (ArrowMonad a)

今回はこの束縛をなくし、多相性を完全に保ったままMonadを導出します。
すなわち、

ArrowMonadExt
newtype ArrowMonadExt a b c =
    ArrowMonadExt { runArrowMonadExt :: (a b c) }
forall a b. Arrow a => instance Functor (ArrowMonadExt a b)
forall a b. Arrow a => instance Applicative (ArrowMonadExt a b)
forall a b. ArrowApply a => instance Monad (ArrowMonadExt a b)

を定義します。ArrowMonadの時はインスタンス宣言の型変数が一つだった(forall a.)のに対し、ArrowMonadExtの定義では型変数が二つになっている(forall a b.)点がミソです。

共通ヘッダー

この記事のソースコードをコンパイルするには、各ソースコードの冒頭に以下を追加してください。

{-# LANGUAGE Arrows #-}
import Control.Arrow

ArrowMonadExtの定義

newtype ArrowMonadExt a b c =
    ArrowMonadExt { runArrowMonadExt :: (a b c) }

Functorの定義

instance (Arrow a) => Functor (ArrowMonadExt a b) where
    fmap f (ArrowMonadExt m) = ArrowMonadExt $
        proc b -> do
            c <- m -< b
            returnA -< f c

Applicativeの定義

instance (Arrow a) => Applicative (ArrowMonadExt a b) where
    pure x = ArrowMonadExt $
        proc _ -> returnA -< x

    (ArrowMonadExt l) <*> (ArrowMonadExt m) = ArrowMonadExt $
        proc b -> do
            f <- l -< b
            c <- m -< b
            returnA -< f c

Monadの定義

instance (ArrowApply a) => Monad (ArrowMonadExt a b) where
    (ArrowMonadExt m) >>= k = ArrowMonadExt $
        proc b -> do
            c <- m -< b
            d <- runArrowMonadExt $ k c -<< b
            returnA -< d
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away