2016-06-23 12 views
0

作業の方法、例えば
組成物 - 私はHaskellで構図を作業の方法を理解することはできません

((.) . (+)) 3 (*2) 9 = 9 * 2 + 3 = 21 この答えはGHCiのによって生成されます。私にとって
が、それは次のようになります。
((.) . (+)) 3 (*2) 9 = (3+9) * 2 と似((.) . (+))のタイプはNum c => c -> (a -> c) -> a -> c

である理由、私は理解できない、あなたはそれを私に説明しようとすることはできますか?

+0

はあなたの推論を表示します。 –

答えて

1

この式では、(.)(+)の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で統一されています

部分アプリケーションを実行すると、最初の引数は(.)になります(これには値が与えられているため)。残りのbcを新しいタイプに置き換えて型を調べます。

(.)  :: (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 

(.) (.)の型にat、および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 
+0

私は今、あなたが知っていることから、(b - > c)、(t - > u) - >(s - > t) - > s - > u' –