言語ゲーム

とあるエンジニアが嘘ばかり書く日記

Twitter: @propella

自然変換に挑戦

(下に書いてあることは嘘なので気を付けてください。分かったら書き直します)

http://d.hatena.ne.jp/propella/20070813/p1 でいかにも自然変換について分かったような事を書いてしまったけど、あとで圏論の基礎の説明を読んでもさっぱり分かりませんでした。ので、http://www.haskell.org/haskellwiki/Category_theory/Natural_transformation を読みながら別の例で試してみます。

Hugs> :load Maybe
Maybe> map even $ maybeToList $ Just 5  -- 「たぶん5」→「5のリスト」→「Falseのリスト」
[False]
Maybe> maybeToList $ fmap even $ Just 5 -- 「たぶん5」→「たぶんFalse」→「Falseのリスト」
[False]

この場合、自然変換に当たるのはどれでしょう?

自然変換の定義。びっくりしないように射も函手も関数と呼びます。

  • B と C が圏の時(圏とは、要素と関数をまとめて呼んだ物です)。
  • B の要素 b1, b2 を b1 -> b2 のように変換する関数 f がある時。
  • T と S が B -> C の関数の時。
    • (T が B の要素を C の要素に変換し、T が B の関数を C の関数に変換するという意味)
  • b が B の要素なら、T(b), S(b) はどちらも C の要素です。
  • x, y を B の要素とします。

以下の関係を保つ関数τを自然変換と呼びます。(注: 以下の要素も関数も全部 C の要素です)。

T(x) --- T(f) --> T(y)
  |                |
  |                |
τ(x)             τ(y)
  |                |
  V                V
S(x) --- S(f) --> S(y)

haskell の例を当てはめます。

  • B には Int, Bool, even が含まれます。
  • C には Maybe Int, [Bool], map even などが含まれます。
  • f は even :: Int -> Bool です。
  • T は Just や fmap :: Int -> Maybe Int です。
  • S は [] や map :: Int -> [Int] です。
  • そして自然変換τは maybeToList :: Maybe Int -> [Int] です。
Just 5 ---- fmap even ---> Just false
     |                         |
     |                         |
maybeToList (Just 5)      maybeToList (Just false)
     |                         |
     V                         V
   [5] ---- map even  ----> [false]

ややこしい部分は、圏の要素は Int や Bool であって 5 や false では無いところ。上の図は間違いか?「b1 -> b2 のように変換する関数 f」では無くて、型が b1 -> b2 である関数 f と書いたほうが良かったのかな?とりあえず滅茶苦茶難しいので後で考えます。