45

私は過去 1 年ほどの間、Haskell をいじっていましたが、モナド、レンズ、型ファミリまで、実際に「理解」し始めています。

私はこのコンフォート ゾーンを少し離れようとしており、日常業務として OCaml プロジェクトに移行しています。構文を少し調べて、ファンクターなどの同様のより高いレベルの概念を探していました。

OCaml のコードとファンクターの構造を読みましたが、Haskell と OCaml で同じような概念になっているかどうかはわかりません。簡単に言えば、Haskell のファンクターは、主に Haskell で関数を持ち上げる方法であり、そのように使用します (そして気に入っています)。OCamlでは、インターフェースへのプログラミングに近いと感じます(たとえば、その比較関数を使用してセットまたはリストを作成する場合)。たとえば、ファンクターなどで関数を持ち上げる方法が本当にわかりません。

2 つの概念が似ているかどうかを誰かに説明してもらえますか? 少しググったところ、明確な答えが見つからないようです。

カスパー

4

1 に答える 1

48

実用的な観点からは、OCaml と Haskell の「ファンクタ」は無関係と考えることができます。あなたが言ったように、Haskell では、ファンクターは、関数をその上にマップできる任意の型です。OCaml では、ファンクタは別のモジュールによってパラメータ化されたモジュールです。

関数型プログラミングでは、ファンクターとは何ですか? には、2 つの言語のファンクターとは何か、そしてそれらがどのように異なるのかがよく説明されています。

しかし、名前が示すように、一見異なる 2 つの概念の間には実際には関連性があります。両方の言語の関手は、圏論からの概念の単なる実現です。

圏論は圏の研究であり、圏はそれらの間に「射」を持つオブジェクトの単なる任意の集まりです。圏の考え方は非常に抽象的なので、「オブジェクト」と「射」は実際にはいくつかの制限があれば何でもありえます。すべてのオブジェクトに単位射が存在しなければならず、射が構成しなければなりません。

カテゴリの最も明白な例は、セットと関数のカテゴリです。セットはオブジェクトであり、セット間の関数は射です。明らかに、すべてのセットには恒等関数があり、関数を構成できます。Haskell や OCaml などの関数型プログラミング言語を見ると、非常によく似たカテゴリを形成できます。具象型 (たとえば、 kind を持つ型*) はオブジェクトであり、Haskell/OCaml 関数はそれらの間のモーフィズムです。

圏論では、関手は圏間の変換です。カテゴリー間の機能のようなものです。Haskell の型のカテゴリを見ると、ファンクタは基本的に型レベルの関数です。つまり、型を別のものにマップします。私たちが気にする特定の種類のファンクターは、型を他の型にマップします。これの完璧な例は次のMaybeとおりです。すべての可能な Haskell タイプのマッピングを提供します。MaybeIntMaybe IntStringMaybe String

ファンクタにはもう 1 つの要件があります。オブジェクトだけでなく、カテゴリのモーフィズムもマッピングする必要があります。特に、射がA → Bあり、ファンクターがおよびに写像Aする場合、射を何らかの 射に写像する必要があります。具体的な例として、型とがあるとしましょう。Haskell の関数はたくさんあります。適切な関手であるためには、これらのそれぞれに対して関数を持たなければなりません。A'BB'A → BA' → B'IntStringInt → StringMaybeMaybe Int → Maybe String

幸いなことに、これはまさにfmap関数が行うことであり、関数をマップします。の場合Maybe、タイプは(a → b) → Maybe a → Maybe b; get: にいくつかの括弧を追加できます(a → b) → (Maybe a → Maybe b)。この型シグネチャが教えてくれるのは、私たちが持っている通常の関数には、対応するMaybes 上の関数もあるということです。

したがって、ファンクターは、タイプ間の関数も保持するタイプ間のマッピングです。fmap関数は基本的に、ファンクターに対するこの 2 番目の制限の証明にすぎません。Functorこれにより、Haskellクラスが数学概念の特定のバージョンにすぎないことが簡単にわかります。

では、OCaml はどうでしょうか。OCaml では、ファンクターは型ではなく、モジュールです。特に、これはパラメータ化されたモジュールです: 別のモジュールを引数として取るモジュールです。すでにいくつかの類似点が見られます。Haskell では、aFunctorは型レベル関数のようなものです。OCaml では、ファンクターはモジュールレベルの関数のようなものです。本当に、それは同じ数学的アイデアです。ただし、 Haskell のようにで使用される代わりに、モジュールで使用されます。

OCaml ファンクターがどのように圏論ファンクターに関連しているかについては、CS サイトのはるかに詳細な情報があります: What is the relationship between functors in SML and Category theory? . 質問は OCaml そのものではなく SML に関するものですが、私の理解では、OCaml のモジュール システムは SML のモジュール システムと非常に密接に関連しています

要約すると、Haskell と OCaml のファンクターは 2 つの根本的に異なる構造であり、どちらもたまたま同じ非常に抽象的な数学的アイデアの具体化になっています。私はそれがかなりきちんとしていると思います:)。

于 2013-05-03T07:23:57.677 に答える