2016-05-16 6 views
0

私はHaskellを学び始めます。チュートリアルを勉強しながら、私は算術式の関数の使用を可能にする次の例を見つけました:この例はうまくいきません。しかし、私はどのように(+)関数が2つの引数の関数に変換されるのか理解できません。私はそれぞれ(+)fun2 (+)に置き換えられていると理解しています。 fun2は1つの引数\t -> a t 'op' b tの関数に相当しますが、2つの引数の関数((\t1 t2 -> (\x -> x) t1 + (\x -> x) t2)のようなもの)が必要です。ここでは、Haskellの型定義の基本的な概念をいくつか適用する必要があると思いますが、それらが何であるか分かりません。ハスケル。 Num式の関数

EDIT 1

私はfun2は3つの引数の関数であることを理解しています。私は内部表現の変換を理解できません。私は次のように推論しています:(+) 3 4 = (+) (\x->3) (\x->4) = fun2 (+) (\x->3) (\x->4) = \t -> (\x->3) t + (\x->4) t これは何ですか?私の推論でどこが間違っていますか?別の方法で考える必要があるかもしれませんか?

EDIT 2

は、私が(おかげであなたのすべて!)私は、問題のいくつかの理解に達していると思います。だから、:

  1. 我々は(+) 3 4書く - Numからこの場合の簡単な操作は、FunNatからの特別な機能を使用されていません。 FunNat(+)を使用するには、fun2 (+) 3 4またはfun2 (+) (\x -> 3) (\x -> 4)と記述する必要があります。しかし、これらの式は、第3のパラメータが評価されることを期待しています。

  2. FunNatの具体的な機能を示すには、((*)-(+))(チュートリアルから引用)または他の形式 - (-) (*) (+)を使用することができます。どちらの式も2つの引数をとります。この場合、私たちは:((*)-(+)) = fun2 (-) (*) (+) = \t -> (*) t - (+) t = \t -> (\t1 t2 -> t1 * t2) t - (\t1 t2 -> t1 + t2) t = (\t t2 -> t * t2) - (\t t2 -> t + t2) = \t t2 -> (t * t2) - (t + t2)です。最終的な式はちょうどNumであると想定しています。から取られた(私はそれがチュートリアルで説明したように、これらすべてが

  3. 正しいことを願っていますが、(t->a)を期待fun2ためのパラメータとして(*)(+)を使用する可能性は、以下に基づいており、ために私は何を理解することはできませんチュートリアル):t1 -> t2 -> a = t1->a'a' = t2 -> a。ここでカーリングが使用されます。

したがって、すべての必要な事実は表面上にありましたが、私は型推論の非自明なメカニズムを考慮しません。タイプで

+0

'fun2(+)'は、定義によって '\ a b t - > a t + b t 'に相当します。これは本当に3つの引数の関数です - その型は 'Num a => {-1 - }(t - > a) - > {-2 - }(t - > a) - > {-3-} t - > a ' – user2407038

+0

ありがとうございました。私は問題を明確にしようとします。 – DrDecay

+0

@あなたの編集.. 't'はラムダによって束縛される変数です。 '(\ x - > 3)t'はちょうど' 3'なので、 '\ t - > 3 + 4'が最終式です。 – user2407038

答えて

0

署名括弧右に関連付けるので:

f :: a -> (b -> c -> d) 

と同じである。

f :: a -> b -> c -> d 

だから括弧は、以下に示す冗長である:

fun2 :: (a -> b -> c) -> ((t -> a) -> (t -> b) -> (t -> c)) 
         ^       ^

とそれらを取り除く:

fun2 :: (a -> b -> c) -> (t -> a) -> (t -> b) -> (t -> c) 
      arg1    arg2  arg3 
+0

ありがとうございました。私は問題を明確にしようとします。 – DrDecay

1

(+)のタイプはNum a => a -> a -> aです。あなたがタイプNum a => t -> aためNumのインスタンスを作成しているので、(カリー化による)(1)

または同等に明示的な署名に

(+) :: Num a => (t -> a) -> (t -> a) -> (t -> a)を検討

(+) :: Num a => (t -> a) -> (t -> a) -> t -> a(2)

何これ「tからNum a => aを作成する2つの戦略を教えていただければ、を使用してtからNum a => aを生成するための新しい戦略を作成できますこの具体的な(+)は、関数(1)を返す2つの引数、または返す3つの引数の関数として見ることができると思います。値(2)。 Haskellの関数はカレー化されているので、これらは実際は同じものです。

関連する問題