2009-05-03 13 views
4

この質問は、優秀なファンタジーの新しい章を読んでいる間に、アプリケーション・ファンクターについてのハスケルです。ハスケルはどのtypeclassインスタンスを意味するのですか?

のApplicative型クラスは、たぶん、インスタンスの定義の一部として、があります。

pure = Just 

私はちょうどGHCiのと輸入Control.Applicativeに行き、そしてそうした場合:

pure (3+) 

Iドンちょうど何かを得る(意味をなさない)。私は式の一部でそれを使用する場合でも:

pure (3+) <*> Just 4 

私はそこにあることを、私はそれはまた、驚くべきことではないと思いますが、私は型クラスがどのように動作するかについての不可欠な何かが欠けている、と思うだけで7を取得しますpureへのコールとあいまいさはありません。

私の混乱が理にかなっている場合は、誰でも詳細なことを説明できますか?

答えて

6

これは単なる推論です。 (<*>)演算子は、同じApplicativeインスタンスを使用するには、両方の引数が必要です。右側はMaybeなので、左側もMaybeでなければなりません。それで、ここでどのインスタンスが使われているかがわかります。あなたは:t expressionとタイプしてインタプリタの式のタイプを調べることができます。そして、各サブ式を調べて、推論されたタイプを調べるだけで、何が起こっているのかをより正確に把握できます。

+0

ああ、コンパイラは "うーん、この引数の型はあいまいなので、次の引数の型をチェックして戻ってくる"のようなことをしますか? –

+8

型推論はかなり複雑ですが、それは一段階で起こらないことを知る価値があります。型推論は、通常、あるステップでいくつかの情報を収集し、後の段階ではいくつかの情報を収集します。つまり、左から右に向かって、すべてのものに対して正しいタイプを推論するだけではありません。この場合、純粋な型は 'a1(Int-> Int)'型であり、 'a1'は単にタイプアップされた型変数であり、型推論の後の段階では(Applicative a1)=> a1 'a1'は' Maybe'でなければならないと結論づけ、どこでも 'a1'を' Maybe'に置き換えます。 –

+0

ありがとうございます - それはとても役に立ちます! –

2

実際の型を推測するのに十分な情報がない場合、コンパイラはデフォルトの型を選択しようとします(場合によっては型の制約を満たすものに限定されます)。質問。この場合、推測される型は、Num => nのいくつかの決定が困難なインスタンスのIO(n - > n)です。 GHCiはそれを評価し、戻り値をスローします。

3

これは、コンパイラがpure (3+)のために推論種類を見て価値がある:

Prelude Control.Applicative> :t pure (3+) 
pure (3+) :: (Num a, Applicative f) => f (a -> a) 

この用語の種類が過負荷になっている、と数値クラスについての決定及び応用的クラスが後まで遅延されます。しかし、あなたは、たとえば、アノテーションで特定の型を強制することができます

*Showfun Control.Applicative> pure (3+) :: Maybe (Double -> Double) 
Just <function> 

を(Showfun<function>として関数値を出力するインスタンス宣言を持っているので、これは動作します。)

それはの問題だけですコンパイラは十分な情報を蓄積して決定を下しました。

+0

好奇心をそそり、既存のパッケージの 'Showfun'モジュールですか、あなた自身が書いたものですか?この実装は十分に簡単です: 'インスタンスShow(a - > b)where where; show _ = "" –

+0

私はShowfunを自分で書いたので、 'Just 'を使って印刷するには' pure(3+) 'の例を得ることができました。 –

+0

ShowFunctionsは現在QuickCheckに入っています。 – porges

1

興味深いのはSO thread on type inferenceです。ハスケル特有のものではありませんが、機能的な言語で型推論を読むための良いリンクやものがたくさんあります。

関連する問題