2013-09-04 7 views
9

この機能は、間違っているとコンパイルされません。Numを0と比較できないのはなぜですか?

checkIsZero :: (Num a) => a -> String 
checkIsZero a = if a == 0 
        then "Zero" 
        else "Not zero" 

これが原因で表現a == 0Num0との比較では動作しません。 NumからIntegralに変更すると、これが有効な機能になります。

0に私の番号を比較させないこの邪悪な魔法は何ですか?

+0

として定義され、numの動作するようです。 ghcを使用していますか?エラーメッセージは何ですか? – jev

+0

私は上記の関数を 'functions.hs'に入れ、' ghci'の ':lfunction.hs'を実行し、' == '' –

+3

@jevの使用から生じるエラーを'推測できません(Eq a) GHC 7.4以来、少なくともその型署名では動作しません。 'Eq'は' Num 'によってもはや暗示されません。 –

答えて

23

Num+*abssignum、およびfromIntegerを実装するためのインスタンスが必要です。 ==がリストにないことに注意してください。 ==を実装しなければならないのは、Eqタイプキャストのインスタンスです。

したがって、Numという制約は十分ではありません。Eqという制約も必要です。以下がコンパイルされます。

checkIsZero :: (Eq a, Num a) => a -> String 
checkIsZero a | a == 0 = "Zero" 
       | otherwise = "Not zero" 

Integral作品Integralのインスタンスである何かが順番にEqのインスタンスでなければならない、Ordのインスタンス自体でなければなりませんので。

hoogleを使用してこれらのすべてをチェックして、ソースを掘り下げることができます。

+0

クイックコメント - 「Integral」クラスは、ハスケルの数値型クラスが壊れているもう一つの例だと思います。捕捉しようとする概念は、「残余と分けることができる操作」です。数学では、それを「ユークリッド・ドメイン」と呼びます。これには、ガウス整数、多項式環、べき級数などのオブジェクトが含まれていますが、必ずしも分かりやすい「Ord」インスタンスを持たず、整数への埋め込みを許可しません'toInteger 'によって要求される)。むしろ、「EuclideanDomain」クラスと別の「Integral」クラスを参照したいと思います。整数Z、p/Zをpプライムにする。 –

10

Numインスタンスを定義するためにEqインスタンスを必要としない理由は、あなたが関数のEqインスタンスを作成することができないので、それが

instance Num b => Num (a -> b) where 
    f + g = \x -> f x + g x 
    f - g = \x -> f x - g x 
    f * x = \x -> f x * g x 
    abs f = \x -> abs (f x) 
    signum f = \x -> signum (f x) 
    fromInteger = const . fromInteger 

のような便利なインスタンスを除外するだろうということです。

+4

これは、そのような関数のインスタンスだけでなく、シンボリックな代数型、無限精度の実数、自動派生型にも適用されます。 – leftaroundabout

+2

私は、与えられたインスタンスのあなたの記述を「有用」と主張する人もいると思います! –

+5

@BenMillwood私は、それらの人々は十分に想像力がないと言いたい。サンプルユースケースについては、[本書](http://conal.net/papers/beautiful-differentiation/beautiful-differentiation.pdf)を参照してください。ここには、Haskellで自動微分を実装する簡単な方法が記載されています。これには、 'cos log(log(x)の微分はxの逆数である)。 –

0

データがNum aのインスタンスである場合、そのデータはEq aのインスタンスであることが受給者ではありません。

Integer(およびIntDouble)両方のインスタンスがあります。instance Num Integerinstance Eq Integerを、そしてプログラムが有効

IntegralですがGHCiの中

class (Real a, Enum a)=> Integral a where ... 
class (Num a, Ord a)=> Real a where ... 
class Eq a => Ord a where ... 

~= class (Num a, Eq a, Enum a)=> Integral a where ... --means 
+0

私の 'ghci'は' Eq'ではなく 'Ord'が' Real'のスーパークラスだと言っています。 –

+0

@ベンミルウッド:ありがとうございます。私が直します。 – wit

関連する問題