22

GHCi がどのように整数型を想定しているかについて質問があります。

Learn you a Haskell の Yes-No 型クラスを読んでいました。

全文読みたい方はこちらのリンクからどうぞ。 http://learnyouahaskell.com/making-our-own-types-and-typeclasses#a-yes-no-typeclass

簡単に言えば、この章では、独自のクラスを定義することで、多くの型で動作する関数を作成できることを示しています。

この本では、関数を使用して YesNo クラスを定義しています

yesno :: a -> Bool

IntYesNoクラスのインスタンスとして作る

instance YesNo Int where
    yesno 0 = False
    yesno _ = True

これをGHCiにロードして入力したとき

yesno 0

エラーを返しました。おそらく、GHCi は 0 がクラス内の他の型であるIntInteger、またはDoubleその他の型であるかを判断できないためだと思いました。Num実際に yesno (0::Int) と入力すると、うまくいきました。

楽しみのために、クラスIntegerのインスタンスとして作成し、YesNo書きました

instance YesNo Integer where
    yesno 0 = True
    yesno _ = False

(True と False を反転したことに注意してください)、もう一度入力します

yesno 0

(型宣言なし) GHCi は を示しTrueました。

さらに、私がタイプしたとき

yesno $ fromIntegral 0

これはTrue、GHCi が の型をfromIntegral 0isと見なしていることを意味しIntegerます。

では、GHCi で整数を入力すると、通常はその値Integer:t 0返品するので迷っていますNum a => a

4

3 に答える 3

26

これは、ghci の拡張されたデフォルト ルールと一緒に型のデフォルト化を行います。

整数リテラルは多相的であり、型を持っていますNum a => a( を表すためfromInteger literal)。しかし、式を評価する必要がある場合 (たとえば、その結果を出力するために必要)、式には単相型を指定する必要があります。

それ自体で、

yesno 0

に と の 2 つの制約Num aYesNo a課す0と、式全体があいまいな型になります。

yesno 0 :: (Num a, YesNo a) => Bool

(制約の型変数は の右側の型から到達できないため、あいまいです=>)。

一般に、あいまいな型は型エラーですが、場合によっては、制約された型変数を既定の型でインスタンス化することで、あいまいさが解決されます。言語仕様のルールは、次の場合に型変数をデフォルトにできるというものです。

あいまいな型が発見された状況では、あいまいな型変数vは次の場合にデフォルト可能です。

- `v` appears only in constraints of the form `C v`, where `C` is a class, and
- at least one of these classes is a numeric class, (that is, `Num` or a subclass of `Num`), and
- all of these classes are defined in the Prelude or a standard library (Figures 6.2–6.3 show the numeric classes, and Figure 6.1 shows the classes defined in the Prelude.)

この制約(Num a, YesNo a)は最初の 2 つの要件を満たしていますが、3 番目の要件を満たしていません。そのため、言語標準では、デフォルトではなく、型エラーになるはずです。

ただし、ghci は拡張された既定の規則を使用し、Prelude または標準ライブラリで定義されていないクラスによって制約される既定の型変数も使用します。

Num次に、明示的なデフォルト宣言がスコープ内にない限り、ここで制約のデフォルトを選択するか、制約を満たさないInteger場合は試行されます。IntegerDouble

したがって、 がある場合instance YesNo Integer、ghci は型変数aを に正常にデフォルト設定できますInteger。しかし、そのようなインスタンスが利用できない場合、既定の候補のいずれにもインスタンスがないため、既定の設定は失敗します。

于 2013-05-29T21:37:43.877 に答える