Haskell はどのタイプクラスのインスタンスを意味しているのかをどのようにして認識するのでしょうか?
-
03-07-2019 - |
質問
この疑問は、優れた『Learn You a Haskell』のアプリカティブファンクターに関する新しい章を読んでいるときに生じました。
Applicative タイプクラスには、Maybe インスタンスの定義の一部として次のものが含まれます。
pure = Just
GHCi に移動して Control.Applicative をインポートし、次のようにすると:
pure (3+)
何もわかりません(意味はわかります)。しかし、式の一部でそれを使用すると、次のようになります。
pure (3+) <*> Just 4
ジャスト7を取得します。これも驚くべきことではないと思いますが、型クラスがどのように機能するかについて重要な点が欠けています。つまり、次の呼び出しに曖昧さはないのだと思います。 pure
ここ。
私の混乱が理解できるとしたら、何が起こっているのか詳しく説明してくれる人はいますか?
解決
これは単なる型推論です。 (&lt; *&gt;)
演算子では、同じ Applicative
インスタンスを使用するために両方の引数が必要です。右側は Maybe
なので、左側も Maybe
でなければなりません。そのため、ここでどのインスタンスが使用されているかがわかります。 :t expression
と入力することで、インタープリターで式の型を確認できます。また、各部分式を調べて、推論された型を確認するだけで、何が起こっているのか。
他のヒント
コンパイラが 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
に関数値を&lt; function&gt;
として出力するインスタンス宣言があるため機能します。)
これは、コンパイラが決定を下すのに十分な情報をいつ蓄積したかという問題です。
newacctの答えを少し拡張するために、実際の型を推測するのに十分な情報がない場合、コンパイラは(場合によっては)問題の型制約を満たすものに限定されたデフォルト型を選択しようとすることがあります。この場合、推測が困難なNumのインスタンスの場合、推測されるタイプはIO(n->; n)です。 n。 GHCiはそれを評価し、目に見える効果なしに戻り値を捨てます。
ここに興味深いものがあります 型推論に関する SO スレッド. 。Haskell 固有のものではありませんが、関数型言語の型推論について読むべき良いリンクや内容がたくさんあります。