らんだむな記憶

blogというものを体験してみようか!的なー

圏論(25)とHaskellと

妄想を炸裂させてみる。
Haskellの世界にHaskellの圏 Haskell とかいうのがあるとかないとかよく知らない。
こいつについて何も知らないが妄想してみよう。

  • Objects: Haskellの型; Integer, Double, [Char], (Integer, Char), Integer -> Integer, ...
  • Arrows: Haskellの関数(カリー化された関数*1 )

といったところだろうか。
副作用がないことから、結合則などはそのまま成立しているだろう。arrow の domain はその arrow に対応する関数の入力引数の型で、codomain は戻り値の型になる。
後ほど触れる identity arrows と併せてHaskellという圏が考えられそうであることが分かる。

少しサンプルを考える。

[pow.hs]

pow :: Integer -> Integer -> Integer
pow x n = x^n

Prelude> :l pow.hs
[1 of 1] Compiling Main             ( pow.hs, interpreted )
Ok, modules loaded: Main.

というように load すると、

*Main> :t pow
pow :: Integer -> Integer -> Integer

となっている。ここではカリー化を考えたいのだが、

*Main> let pow2 = pow 2
*Main> :t pow2
pow2 :: Integer -> Integer

からも分かるように、

*Main> :t pow 2
pow 2 :: Integer -> Integer

となっている。要するに「pow 2 3 = ( (pow 2) 3)」であって「pow」は「Integer」の型のオブジェクトを引数にとり「Integer -> Integer」という型の関数を返す関数である。
このように関数は常にカリー化して考えることでHaskellの arrows として解釈できそうである。uncarry する*2ことは arrows の composite を考えることに相当すると思う。

別の関数として

identity x = x

を考える。

*Main> let hoge = identity pow2
*Main> hoge 3
8

のように関数を含めて、受け取ったオブジェクトをそのまま返す関数である。
これが圏Haskellにおける identity arrow になると考えられる。

ところで、

*Main> :t identity
identity :: t -> t

からも分かるように、上で用意した関数 identity はそれ自身では引数の型と戻り値の型を持たず、domain と codomain が定義できない状態にあり、圏の射としては不適切となる。
要するにテンプレート状態なのである。また、

Prelude> :t (>)
(>) :: Ord a => a -> a -> Bool

のように引数の constraint として Ord が指定されている程度であとは知らね!という感じの関数もある。オブジェクトの詳細に依存せず、インターフェイスのみで実装されているのである。
identity にせよ > にせよ非常に polymorphic な関数であり、具体的な型を持った引数を与えて初めて関数の型が定義される。
(Integer), (Integer, Integer), (Integer, Integer, Integer), ... というように無限の tuple を考えると分かるように、無限の型が考えられるので、Haskellの objects は無限にあり、従って、identity arrows も無限にある。

特にまとめも何もないが、Haskell(だと思い込んでいるもの)を考えると、arrows そのものではなく、arrows を与える polymorphic なテンプレートという存在がでてきた。ポリモーフィズム(polymorphism)はよく「多相性」だとか「多態性」と訳されるが明らかに「poly-morphism」と分解できる。そう、「morphism」― 射 ― である。これは何か関係があるのだろうか?

正直、Haskell というプログラミング言語を理解する上でこのようなことを考えることに何の意味があるのか分からないし、ライブラリを使う上でこんなことを知らないと使えないようなら相当不出来だと思う。高速フーリエ変換のライブラリを使う上で高速フーリエ変換の原理など知る必要があるだろうか?否。フーリエ変換がどういうものでライブラリをどう使えば良いかのみ理解していれば十分のはずである。
さて、まぁ圏論に落とし込むことはできそうだなとぼんやり思うものの、その必要性はまだまだ感じることはない。

*1:1つの引数をとり1つの戻り値を返す関数という意味で用いている。

*2:非カリー化するなどと呼ぶらしい...?