4

私は最近haskellで遊び始めましたが、このおもちゃの例で説明できるHashMapの使用中に問題が発生しました。

import Data.HashMap as HashMap

foo = HashMap.insert 42 53 HashMap.empty

インタプリタにファイルをロードしたり、コンパイルしたりすると、次のエラーが発生します。

Prelude List HashMap> :load TypeError.hs
[1 of 1] Compiling Main             ( TypeError.hs, interpreted )

TypeError.hs:3:22:
    Ambiguous type variable `k0' in the constraints:
      (Num k0) arising from the literal `42' at TypeError.hs:3:22-23
      (Ord k0) arising from a use of `insert' at TypeError.hs:3:7-20
      (Data.Hashable.Hashable k0)
        arising from a use of `insert' at TypeError.hs:3:7-20
    Possible cause: the monomorphism restriction applied to the following:
      foo :: Map k0 Integer (bound at TypeError.hs:3:1)
    Probable fix: give these definition(s) an explicit type signature
                  or use -XNoMonomorphismRestriction
    In the first argument of `insert', namely `42'
    In the expression: insert 42 53 empty
    In an equation for `foo': foo = insert 42 53 empty
Failed, modules loaded: none.
Prelude List HashMap>

ただし、インタプリタでまったく同じ関数を直接定義しても、エラーは発生しません。

Prelude List HashMap> let foo = HashMap.insert 42 53 HashMap.empty
Prelude List HashMap>

誰かがこれについて何か手がかりを持っていますか?

ありがとう。

4

1 に答える 1

6

その理由は、ghciが拡張デフォルトルールを使用しているのに対し、コンパイラは(デフォルトで)言語レポートで指定されているデフォルトルールを使用しているためです。

クラスNumのあいまいさは最も一般的であるため、Haskellはそれらを解決する別の方法を提供します。デフォルトの宣言:default(t1、…、tn)ここでn≥0であり、各tiはNumtiが保持する型でなければなりません。あいまいな型が発見された状況では、次の場合にあいまいな型変数vがデフォルトになります。

  • vは、C vの形式の制約でのみ表示されます。ここで、Cはクラスであり、
  • これらのクラスの少なくとも1つは、数値クラス(つまり、NumまたはNumのサブクラス)であり、
  • これらのクラスはすべて、プレリュードまたは標準ライブラリで定義されています

関連するルールは、レポートごとにデフォルト設定が行われるのは、関連するすべてのクラスが標準ライブラリで定義されている場合のみですがHashable、キーの制約には、その要件を満たさないクラスが含まれます。

したがって、コンパイラはそれを拒否します。これは、キーから生じるあいまいな型変数を解決できないためです。一方、Integerghciは、他のクラスが関係している場合もデフォルトになるため、デフォルトでに設定されます。

于 2012-12-06T20:42:08.987 に答える