我仍然非常想进入哈斯克尔,但我注意到一些令我恼火的东西。
在书"Learn You a Haskell for Great Good!"中,这部分显示了在模式匹配中使用防护,在本书的情况下它是一个计算人的bmi的小函数,它有点像这样的东西(部分略有变化,不侵犯版权或其他):
bmiCalc :: (RealFloat a) => a -> a -> String
bmiCalc weight height
| bmi <= 18.5 = "skinny"
| bmi <= 25.0 = "normal"
| bmi <= 30.0 = "fat"
| otherwise = "obese"
where bmi = weight / height ^ 2
这一切都很好,花花公子的代码就像宣传的那样,但我想,如果它还显示了它计算的bmi与文本一起会怎么样?
所以我重新编写了代码:
bmiCalc :: (RealFloat a) => a -> a -> String
bmiCalc weight height
| bmi <= 18.5 = "skinny, " ++ show bmi
| bmi <= 25.0 = "normal, " ++ show bmi
| bmi <= 30.0 = "fat, " ++ show bmi
| otherwise = "obese, " ++ show bmi
where bmi = weight / height ^ 2
期望“show”像.toString一样工作在java和c#
中
男孩,我错了。
ghci给了我一个非常讨厌的错误信息:
Could not deduce (Show a) arising from a use of `show'
from the context (RealFloat a)
bound by the type signature for
bmiCalc :: RealFloat a => a -> a -> String
at file.hs:1:16-48
Possible fix:
add (Show a) to the context of
the type signature for bmiCalc :: RealFloat a => a -> a -> String
In the second argument of `(++)', namely `show bmi'
In the expression: "skinny, " ++ show bmi
In an equation for `bmiCalc':
bmiCalc weight height
| bmi <= 18.5 = "skinny, " ++ show bmi
| bmi <= 25.0 = "normal, " ++ show bmi
| bmi <= 30.0 = "fat, " ++ show bmi
| otherwise = "obese, " ++ show bmi
where
bmi = weight / height ^ 2
Failed, modules loaded: none.
为什么?为什么它不允许我追加看起来返回字符串的字符串?我的意思是据我所知,"skinny, " ++ show bmi
是一个字符串...这正是类型签名所说的我必须返回
所以我在这里做错了什么?
答案 0 :(得分:9)
将类型签名更改为:
bmiCalc :: (RealFloat a, Show a) => a -> a -> String
因为你想使用成员函数show
,来自Show
类型类;但是你还没有在函数约束中指定,并且ghci没有办法推断它是正确的。
答案 1 :(得分:2)
RealFloat不是一种可展示的类型。你必须添加一个节目约束。