Applicativeと対応する代数

動機

次のFの形をしたMonadについて考えたかった。

M :: Type
E :: Type

data F a = F M (E -> a)

特に、このようなMonad Fを定めるようなM, E上の代数的構造を明らかにしたかった。

例えば、Writer m a ~ (m, a)Monadのインスタンスには m上のモノイドが1対1に対応するし、 Reader e a ~ (e -> a)は一意な方法でMonadになるが、これには e上の唯一の”余モノイド”(const () :: e -> (), join (,) :: e -> (e,e))が対応する。

こんな感じで、Monad Fに対応する代数は何かを考えていた。

が、何日かトライしたもののこれは相当難しい感じがするので、 まずはApplicative Fに何が対応するのかから考えてみた。

Applicative F の構造

ここから、以下の変数が唐突に出てきたら、暗に”任意のxについて…“等が挿入されていると思ってほしい。

x, y, z :: M
f :: E -> a
g :: E -> b
h :: E -> c

まず、pure :: a -> F aは、次の形しかありえないことを確認しておく。

mPure :: M
pure a = F mPure (const a)

また、Applicativeのインスタンスは、次のprodを与えても決まる。

prod :: F a -> F b -> F (a,b)
prod = liftA2 (,)

MEに関する関数(<>) :: M -> M -> Md :: M -> M -> E -> (E, E)が、 prodの実装と1対1に対応する。

prod (F x f) (F y g) = F (x <> y) ((f *** g) . d x y)

x <> y = case prod (F x id) (F y id) of
  F z _ -> z

d x y = case prod (F x id) (F y id) of
  F _ k -> k

Applicative則を満たすためにmPure, <>, dに必要な制約を書き出せば、(mPure, <>) :: (M, M -> M -> M)M上のモノイドを定めることがわかり、さらにdについても条件を得られる。

-- 右単位
-- 正確なHaskellではないが mPure = 1 と略記する
prod (F (x,f)) (pure b) = (,b) <$> F (x, f)
prod (F (x,f)) (pure b)
 = F (x <> 1, (f *** const b) . d x 1)
 = (,b) . F (x,f)

x <> 1 = x            -- (M-unitR)
fst . d x 1 = id
d x 1 = id &&& dl x   -- (d-unitR)
  -- ここで dl :: M -> E -> E はある関数

-- 同様に左単位
1 <> x = x            -- (M-unitL)
snd . d 1 x = id
d 1 x = dr x &&& id   -- (d-unitL)
  -- ここで dr :: M -> E -> E はある関数

-- Applicativeの結合法則

-- 結合法則:
(t `prod` u) `prod` v
 = assoc $ t `prod` (u `prod` v)

(LHS)
  = F (x <> y, f *** g . d x y) `prod` v
  = F ((x <> y) <> z, (f *** g . d x y) *** h . d (x <> y) z)
  = F ((x <> y) <> z,
       first (f *** g) . second h . first (d x y) . d (x <> y) z)
  = F ((x <> y) <> z,
       (f *** g) *** h . first (d x y) . d (x <> y) z)
(RHS)
  = ...(omit)...
  = F (x <> (y <> z),
       assoc . f *** (g *** h) . second (d y z) . d x (y <> z))
  = F (x <> (y <> z),
       (f *** g) *** h . assoc . second (d y z) . d x (y <> z))

(x <> y) <> z = x <> (y <> z) -- (M-assoc)
first (d x y) . d (x <> y) z
 = assoc . second (d y z) . d x (y <> z)  -- (d-assoc)

(M-unitR), (M-unitL), (M-assoc)はモノイド則そのものである。 一方でdに関する法則はあまり明らかでない。

これらの法則はむしろ図に書いたほうがわかりやすい。

    |                 |
 ---+---           +--*--+
  d 1 x     ===    |     |
 -+---+-         --+--   |
  |   |          dr x    |
  |   |          --+--   |
  |   |            |     |

============================================================


    |                |
 ---+---          +--*--+
  d x 1     ===   |     |
 -+---+-          |   --+--
  |   |           |   dl x 
  |   |           |   --+--
  |   |           |     |

============================================================

          |                         |               
   -------+-------           -------+-------        
    d (x <> y) z               d x (y <> z)          
   -+-----------+-           -+-----------+-
    |           |             |           |
 ---+---        |      ===    |        ---+---
  d x y         |             |         d y z
 -+---+-        |             |        -+---+-
  |   |         |             |         |   |

具体例を調べる

Applicativeの具体例を挙げて、ここまで述べた法則が満たされていることを確認していく。

もっとも単純には、Compose (Writer M) (Reader E)と同じ Applicativeのインスタンスが考えられる。これは、

d _ _ = \i -> (i,i)

とした場合に相当する。この定義においてdに関する各法則が成り立つことを確認するのは、 式(d-unitL),etc. を使っても簡単だが、 d _ _ が「入力をただコピーする」ことを図で表した

   |           |
---+---        |
 d _ _   === +-*-+
-+---+-      |   |
 |   |       |   |

を上の3図式に当てはめれば、法則が成り立っていることは自明である。

また、M = E -> E であるとき、 自然同型 F x ~ (E -> E, E -> x) ~ E -> (E, x) ~ State E x が得られるが、State EMonadであり、もちろんApplicativeでもあるので、 F xApplicativeとして得られたことになる。このとき、d

d x _ = \i -> (i, x i)

である。このとき、M上のモノイド演算としては、mempty = idおよび x <> y = x >>> y = y . xが使われている。

モノイド作用によるApplicative

State Eと同型になるケースとの中間例として、 ME上にモノイド作用を持つ場合というものを考えることができる。 モノイドME上への(右)モノイド作用(◁) :: E -> M -> E

i ◁ 1 = i
(i ◁ x) ◁ y = i ◁ (x <> y)

を満たす関数である。モノイド作用を用いて、

d x _ = \i -> (i, i ◁ x)

と書ける場合、これはApplicative則を満たす。上記の定義を図に書くと、

    |                |
    |             +--*---+
 ---+---          |      |
  d x y     ===   |  ----+---
 -+---+-          |   (◁ x)
  |   |           |  ----+---
  |   |           |      |

となる。法則を表す3図式に当てはめれば、

    |                |                  |
    |             +--*---+           +--*--+
 ---+---          |      |           |     |
  d 1 x     ===   |  ----+---  === --+--   |
 -+---+-          |   (◁ 1)        dr x    |
  |   |           |  ----+---      --+--   |
  |   |           |      |           |     |

 (モノイド作用であるから(◁ 1)=idであり、dr x = idとおけばよい。)

============================================================


    |                |                  |
    |             +--*---+           +--*--+
 ---+---          |      |           |     |
  d x 1     ===   |  ----+---  ===   |   --+--
 -+---+-          |   (◁ x)          |   dl x
  |   |           |  ----+---        |   --+--
  |   |           |      |           |     |

 (dl x = (◁ x) とおけばよい)

============================================================

          |                       |               
   -------+-------         -------+-------        
    d (x <> y) z             d x (y <> z)          
   -+-----------+-         -+-----------+-
    |           |           |           |
 ---+---        |    ===    |        ---+---
  d x y         |           |         d y z
 -+---+-        |           |        -+---+-
  |   |         |           |         |   |

        ||                     ||

        |                    |
   +----*-----+           +--*--+
   |          |           |     |   
   |    ------+------     |  ---+---
   |    (◁ (x <> y))      |   (◁ x)
   |    ------+------     |  ---+---
+--*--+       |           |     |
|     |       |           |   +-*---+
|  ---+---    |           |   |     |
|   (◁ x)     |           |   |  ---+---
|  ---+---    |           |   |   (◁ y)
|     |       |           |   |  ---+---
|     |       |           |   |     |

 (モノイド作用の結合法則から両辺は等しい)

今考えたものはモノイド作用であるが、モノイド作用を考えることもできて、 左モノイド作用 (▷) :: M -> E -> E は次式を満たす。

1 ▷ i = i
x ▷ (y ▷ i) = (x <> y) ▷ i

これを用いて、

d _ y = \i -> (y ▷ i, i)

と書ける場合もApplicative則を満たす。右作用と同じように図を描くことでこれも確認できる。

さて、右モノイド作用と左モノイド作用の両方が定義されているとき、次のdを考える。

d x y = \i -> (y ▷ i, i ◁ x)

これは各法則を満たすだろうか?図を書いていくと(AAめっちゃ面倒だったので省略)

(z ▷ i) ◁ x = z ▷ (i ◁ x)

が任意のz,x :: M, i :: Eに対して成り立っているとき、そのときに限り成り立つことがわかる。 これは左右のモノイド作用が可換であることを言っている。 加群の例に倣うなら”E上の(M,M)-両側モノイド作用”とでも呼べばいいだろうか。

具体例を出してみよう。M = E = Intとし、MのモノイドはIntの加法とする。

x ▷ y = x ◁ y = x + y

とすれば、これは左右のモノイド作用を定めており、さらに互いに可換である。

d x y = \i -> (i + y, i + x)

を用いてApplicativeの定義式まで展開してみると、

newtype F x = F (Int, Int -> x)

instance Applicative F where
  pure x = F (0, const x)
  F (x, f) <*> F (y, g) = F (x + y, \i -> f (i + y) (g (i + x)))

である。こんなApplicativeは見たことさえないし、何かの役に立つのかまったくわからないが、 ともかく両側モノイド作用を使って、新しいApplicativeを量産する方法を手に入れたことになる。

一般論に戻って

しかし、本来の疑問はすべてのApplicativeのインスタンスと対応する代数はなにかということだった。 両側モノイド作用によるApplicative以外にもそのような例があるだろうか?

まだ次の疑問が解決していない。

  • 関手F x ~ (M, E -> x)に対するすべての可能なApplicativeのインスタンスは、両側モノイド作用によるものか?

多分違うと思うけれども、反例が思いつかない・・・

また、違うなら違うで、もともとの疑問である

  • 関手F x ~ (M, E -> x)に対するすべての可能なApplicativeのインスタンスは、M, Eに関するどんな代数と対応させられるか?

も考える必要がある。