GHCi が整数の型をどのように想定するかについて質問があります。
私はLearn you a HaskellのYes-No型クラスを読んでいました。
全文を読みたい方は、こちらをクリックしてください。http://learnyouahaskell.com/making-our-own-types-and-typeclasses#a-yes-no-typeclass
簡単に言うと、この章では、独自のクラスを定義することで、多くの型で動作する関数を作成できることを示します。
この本では関数を持つYesNoクラスを定義しています
yesno :: a -> Bool
Int
YesNoクラスのインスタンスとして作成する
instance YesNo Int where
yesno 0 = False
yesno _ = True
これをGHCiにロードして入力すると
yesno 0
Int
エラーが返されました。おそらく、GHCi は 0 がクラス内のor またはInteger
orDouble
またはその他の型であるかどうかを判断できないためだと思いました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 0
であると認識していることを意味しますInteger
。
ということは、GHCiで整数を入力すると、通常はその値がInteger
ではなく であると想定されるということですか?:t 0
返されるので混乱しています。Num a => a
ベストアンサー1
タイプです債務不履行ghci の拡張デフォルト ルールと一緒に使用します。
整数リテラルは多態的であり、 型を持ちますNum a => a
( を表すためfromInteger literal
)。ただし、式を評価する場合 (たとえば、結果を印刷する必要がある場合)、式には単態型を指定する必要があります。
それ自体では、
yesno 0
は、と というNum a
2つの制約を に課し、式全体は曖昧な型を持つことになる。YesNo 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
、 がInteger
制約を満たしていない場合は がDouble
試されます。
したがって、 がある場合instance YesNo Integer
、ghci は型変数a
を にデフォルト設定できますInteger
。ただし、そのようなインスタンスが利用できない場合は、デフォルト候補のいずれにもインスタンスがないため、デフォルト設定は失敗します。