Haskell の通常の関数に対する矢印の利点は何ですか? 彼らができること、機能ができないこと。関数は、fmap を使用して構造体にマップできます。
2 に答える
より広い視野で見ると、矢印はHaskから抜け出し、探索すべき他のカテゴリに移動します。Kleisli カテゴリは、おそらく Haskellers に最もよく知られているカテゴリであり、次にCokleisliです。これらはHaskの自然な「拡張」です: 結果または引数のいずれかにエンドファンクタを追加すると、次の場合に再びカテゴリが得られます。
Kleisli
: ファンクターはモナドなので、id ≅ return :: a -> m a
(.) ≅ (<=<) :: (b->m c) -> (a->m b) -> a->m c
CoKleisli
: ファンクタはコモナドなのでid ≅ coreturn :: m a -> a
、(.) :: (m b->c) -> (m a->b) -> m a->c
Arrow
(そのためには、まだ必要ありませんCategory
。ただし、一般的なカテゴリはあまり興味深いものではありません。通常、モノイドまたはデカルトの閉じたカテゴリが必要です。これは、Arrow
大まかに目指しているものです。)
しかし、他にもたくさんのカテゴリがあります。ほとんどはHaskとはあまり関係がなく、標準Arrow
クラスで表現することはできません。これは主に、すべての Haskell 型が満たすわけではない特別なプロパティがオブジェクトにあるためです。実際、オブジェクトの種類を制限する機能を追加すると、可能性はすぐに広がります. しかし、標準クラスにとどまっていても、単に->
.
関数は矢印のインスタンスにすぎません。それは、「モナドだけではなくモナドを使用する理由」を尋ねるようなものMaybe
です。
インスタンスは関数の小さな部分、つまり型クラスArrow (->)
にあるものについてしか話せないため、アローでできることはすべて関数で行うことができます。Arrow
ただし、アローには単純な関数よりも多くのインスタンスがあるため、ssame 関数を使用してより複雑な型を操作できます。
アローは単なる関数よりも多くの構造を持つことができるので素晴らしいです. justfmap
でトラバースするとき、効果を蓄積する方法がなく、モナドよりも表現力があります! クライスリの矢を考えてみましょう。
newtype Kleisli m a b = Kleisli {runKleisli :: a -> m b}
m
がモナドの場合、これは矢印を形成します。したがって、すべてMonad
が矢印を形成するため、 をシームレスに構成することでモナド計算を構築し、a -> m b
このようなあらゆる種類の便利なことを行うことができます。一部の XML ライブラリでは、矢印を使用して要素からそのサブ要素への関数を抽象化し、これを使用してドキュメントをトラバースします。他のパーサーは矢印を使用しますが (本来の目的)、最近ではこれは支持されなくなっているようですApplicative
。
お気付きだと思いますが、アローはより一般的であるということです。アローについて話すときは、パーサー、xml スクレーパー、およびモナド関数で何かを行うために記述する必要があるすべてのコードを複製することを避けます!
Monad
overを選択するのと同じMaybe
です。特定のステートメントを作成できなくなるため、ある程度の力が失われますが、見返りとしてより一般的なコードが得られます。