この式では、(.)
と(+)
の2つの引数に(.)
が適用されます。一度に1ステップずつ進めましょう。まず、部分的に(.)
を(.)
に適用します。
(.) :: (b -> c) -> (a -> b) -> a -> c
(.) :: (t -> u) -> (s -> t) -> s -> u
今(.) (.)
の種類(一部のアプリケーション)を見て:我々は2つを区別するために、異なるタイプの変数を使用して、ダウン明示的に型シグネチャを書きます。 (これが原因関与型の式のサイズに。次のステップは同じですが、シンプルなタイプで、おそらく最も難しいステップです。)タイプ(b -> c)
の最初の引数、
b ~ t -> u
c ~ (s -> t) -> s -> u
を意味し、
(t -> u) -> (s -> t) -> s -> u
で統一されています
部分アプリケーションを実行すると、最初の引数は(.)
になります(これには値が与えられているため)。残りのb
とc
を新しいタイプに置き換えて型を調べます。
(.) :: (b -> c) -> (a -> b ) -> a -> c
(.) (.) :: (a -> (t -> u)) -> a -> ((s -> t) -> s -> u)
->
が右結合であるため、私たちは今、
(.) (.) :: (a -> t -> u) -> a -> (s -> t) -> s -> u
を取得するために余分な括弧の一部をドロップすることができ、我々は明確にするための新しいタイプの変数を使用して(+) :: Num v => v -> v -> v
から(再び、というを適用)。 (.) (.)
の最初の引数はv -> v -> v
と統一する必要があるタイプa -> t -> u
です。言い換えれば、我々はv
(.) (.) :: (a -> t -> u) -> a -> (s -> t) -> s -> u
(.) (.) (+) :: v -> (s -> v) -> s -> v
で(.) (.)
の型にa
、t
、およびu
のすべての出現を置き換えるだろうと(私たちはバックNum v
制約を追加した後に)あなたが見ることができるように、これは同等ですあなたが見るタイプ:評価されている実際の式については
-- v ~ c, s ~ a
Num v => v -> (s -> v) -> s -> v
Num c => c -> (a -> c) -> a -> c
、
左から右へ((.) . (+)) 3 (*2) 9
は心の中で(.)
f . g = \x -> f (g x)
の定義と仕事を続けます。まず、(.) . (+)
が3
に適用されます。
((.) . (+)) 3 == (.) ((+) 3)
== (.) (3 +)
.
のこの部分的なアプリケーションは、(* 2)
に適用されます。
(.) (3 +) (* 2) == (3 +) . (* 2)
== \x -> (3 +) ((* 2) x)
は最後に、この関数は9に適用されます。
(\x -> (3 +) ((* 2) x)) 9 == (3 +) ((* 2) 9)
== (3 +) (9 * 2)
== 3 + 9 * 2
== 3 + 18
== 21
はあなたの推論を表示します。 –