首页 文章

为什么show不被视为haskell中的转换?

提问于
浏览
5

我仍然非常想进入哈斯克尔,但我注意到一些让我烦恼的东西 .

在书中"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.

这是为什么?为什么't it allow me to append what appears to return a string, to a string? I mean as far as I' ve了解 "skinny, " ++ show bmi 是一个字符串...这正是类型签名所说的我必须返回

那我在这里做错了什么?

2 回答

  • 2

    将类型签名更改为:

    bmiCalc :: (RealFloat a, Show a) => a -> a -> String
    

    因为要使用成员函数 show ,来自 Show 类型类;但是你还没有在函数约束中指定,并且ghci没有办法推断它是正确的 .

  • 9

    RealFloat不是一个可显示的类型 . 你必须添加一个show约束 .

相关问题