Haskellを学んでください、あなたのBMIを計算する例があります。自分でこの例を実行しようとした場合HaskellのRealFloatタイプは何のために使われますか?
bmiTell :: (RealFloat a) => a -> a -> String
bmiTell weight height
| bmi <= skinny = "You're underweight, you emo, you!"
| bmi <= normal = "You're supposedly normal. Pffft, I bet you're ugly!"
| bmi <= fat = "You're fat! Lose some weight, fatty!"
| otherwise = "You're a whale, congratulations!"
where bmi = weight/height^2
(skinny, normal, fat) = (18.5, 25.0, 30.0)
は、私は、メソッドの型署名として(Num a) => a -> a -> String
を用います。しかし、それは、次のエラーがスローされました:
Could not deduce (Ord a) arising from a use of ‘<=’
from the context (Num a)
bound by the type signature for
bmiTell :: Num a => a -> a -> String
at scratch.hs:96:12-38
Possible fix:
add (Ord a) to the context of
the type signature for bmiTell :: Num a => a -> a -> String
私はちょうどNum
とOrd
型クラスを使用してエラーを解決することができませんでした。なぜこのコードを動作させるにはRealFloat
typeclassを使用する必要がありますか? Num
でカバーされていないRealFloat
の特典は何ですか?
GHCがどのようなものであるかを見極めるために型署名を残すようにしてください。必要なすべての制約を正しく識別できる必要があります。この関数定義で使用されている演算子の多くは型抜きからのものなので、これらの型クラスを実装する必要がある型を持つ必要があります。 – bheklilr
@bheklilrああ、うわー、わかるよ。ご意見ありがとうございます。私はそれを試してみました。 GHCは 'bmiTell ::(分数a、Ord a)=> a - > a - > [Char]'をタイプシグネチャとして返しました。これはコードに入力すると明らかに機能します。それは少し意味があります。私はまだ 'bmiTell ::(Num a、Ord a)=> a - > a - > [Char]'がうまくいかない理由について混乱しています。 'Num'型のクラスには複素数も含まれているのでしょうか?複雑な数字は注文できないと思いますか? – user2407334
@ user2407334 'Num'は* too *一般的なもので、'/'が定義されていない' Int'のような型を含みます。 – chepner