http://www.cs.yale.edu/homes/hudak/CS429F04/AFPLectureNotes.pdfをご覧ください。FRP で矢印がどのように機能するかが説明されています。
2 タプルは、2 つの引数を取る矢印化された関数を表す必要があるため、矢印の定義に使用されます。
FRP では、定数と変数は多くの場合、その「入力」を無視する矢印として表されます。
twelve, eleven :: Arrow f => f p Int
twelve = arr (const 12)
eleven = arr (const 11)
次に、関数の適用はコンポジション ( >>>
)に変換されます。
# (6-) 12
arr (6-) <<< twelve
では、引数が 2 つの関数をどのように矢印に変えるのでしょうか? 例えば
(+) :: Num a => a -> a -> a
カリー化により、これを関数を返す関数として扱う場合があります。そう
arr (+) :: (Arrow f, Num a) => f a (a -> a)
これを定数に適用してみましょう
arr (+) -- # f a (a -> a)
<<< twelve -- # f b Int
:: f b (Int -> Int)
+----------+ +-----+ +--------------+
| const 12 |----> | (+) | == | const (+ 12) |
+----------+ +-----+ +--------------+
ちょっと待って、うまくいきません。結果は依然として関数を返す矢印ですが、 に似たものを期待していf Int Int
ます。Arrow では合成のみが許可されているため、カリー化が失敗していることに気付きました。したがって、最初に関数をアンカリー化する必要があります
uncurry :: (a -> b -> c) -> ((a, b) -> c)
uncurry (+) :: Num a => (a, a) -> a
次に、矢印があります
(arr.uncurry) (+) :: (Num a, Arrow f) => f (a, a) a
このため、2タプルが発生します。&&&
次に、これらの 2 タプルを処理するために、次のような束関数が必要です。
(&&&) :: f a b -> f a d -> f a (b, d)
その後、追加を正しく実行できます。
(arr.uncurry) (+) -- # f (a, a) a
<<< twelve -- # f b Int
&&& eleven -- # f b Int
:: f b a
+--------+
|const 12|-----.
+--------+ | +-----+ +----------+
&&&====> | (+) | == | const 23 |
+--------+ | +-----+ +----------+
|const 11|-----'
+--------+
&&&&
(さて、 3 つの引数を持つ関数の 3 タプルのようなものが必要ではないのはなぜですか?((a,b),c)
代わりに a を使用できるためです。)
編集: John Hughes の元の論文Generalising Monads to Arrowsから、理由を次のように述べています。
4.1 アローとペア
しかし、モナドの場合、有用なコードを書き始めるために必要なのは演算子return
とだけですが、アローの場合、類似の演算子とでは十分ではありません。先ほど見た単純なモナド加算関数でさえ>>=
arr
>>>
add :: Monad m => m Int -> m Int -> m Int
add x y = x >>= \u -> (y >>= \v -> return (u + v))
まだ矢印で表現できません。入力への依存を明示的にすると、類似の定義は次の形式を取る必要があることがわかります。
add :: Arrow a => a b Int -> a b Int -> a b Int
add f g = ...
順番にf
組み合わせる必要がある場所。g
使用可能な唯一の順序付け演算子は>>>
, であり、構成する適切な型がf
ありg
ません。実際、add
関数は、同じ入力を に供給できるように、の計算全体で typeの入力を保存する必要があります。同様に、 の結果はの計算全体で保存する必要があります。これにより、最終的に 2 つの結果を加算して返すことができます。これまでに紹介したアロー コンビネータでは、別の計算で値を保存する方法がありません。そのため、別のコンビネータを導入する以外に方法はありません。b
f
g
f
g