25

この機能:

hola :: (Integral a) => a -> String
hola 1 = "OK"
hola _ = "asdf"

正常に動作します。しかし、これは:

hola :: (Num a) => a -> String
hola 1 = "OK"
hola _ = "asdf"

コンパイルできません: 「リテラル `1' から生じる (Eq a) を推測できませんでした」

私は本当にそれを取得しません。私はそれが言われているチュートリアルを読んでいます

「Integral も数値型クラスです。Num には、実数と整数を含むすべての数値が含まれます。Integral には、整数 (整数) のみが含まれます。この型クラスには、Int と Integer があります。」http://learnyouahaskell.com/types-and-typeclasses

Num を使用できないのはなぜですか?

4

2 に答える 2

33

これは、昨年 9 月/10 月に基本パッケージの最新バージョンで提案および承認された最近の変更でEqありShow、もはや のスーパークラスではありませんNum。その変更以来、言語レポートの新しいバージョンは公開されていないため、レポートにはまだ含まれていません。また、最近のことなので、まだ多くのチュートリアルや本にもなっていません。

数値リテラルに対する「パターン マッチング」は の暗黙的な適用で(==)あるため、機能させるEqにはインスタンスが必要です。そのインスタンスは制約から推測できなくなったNumため、(かなり新しい:D) コンパイラはNum制約のみでコードを拒否します。

しかしIntegralは のサブクラスであり、スーパークラスとして(したがって)Realを持っているため、機能します。OrdEq

于 2012-10-07T12:02:36.667 に答える
9

ダニエル・フィッシャーが言ったように、以前は機能していましたが、NumEqが分割されたためNum a機能しなくEq aなりました。コードを修正するには、Eq a明示的にします:

hola :: (Num a, Eq a) => a -> String
hola 1 = "OK"
hola _ = "asdf"
于 2012-10-07T15:45:27.960 に答える