2013-03-29 189 views
3

我是Haskell的新手,遇到类型系统问题。我有以下功能:Haskell类型声明

threshold price qty categorySize 
    | total < categorySize = "Total: " ++ total ++ " is low" 
    | total < categorySize*2 = "Total: " ++ total ++ " is medium" 
    | otherwise = "Total: " ++ total ++ " is high" 
    where total = price * qty 

哈斯克尔与回应:

No instance for (Num [Char]) 
     arising from a use of `*' 
    Possible fix: add an instance declaration for (Num [Char]) 
    In the expression: price * qty 
    In an equation for `total': total = price * qty 
    In an equation for `threshold': 
    ... repeats function definition 

我认为这个问题是我需要以某种方式告诉哈斯克尔总的类型,也许这与类型类展会关联,但我不知道该如何实现。谢谢你的帮助。

回答

10

问题是你定义total为乘法,这迫使它是一个Num a => a然后使用它作为参数传递给++用绳子,迫使它是[Char]的结果。

您需要total转换为String:现在

threshold price qty categorySize 
    | total < categorySize = "Total: " ++ totalStr ++ " is low" 
    | total < categorySize*2 = "Total: " ++ totalStr ++ " is medium" 
    | otherwise    = "Total: " ++ totalStr ++ " is high" 
    where total = price * qty 
      totalStr = show total 

,将运行,但代码看起来有点重复。我会建议这样的事情:

threshold price qty categorySize = "Total: " ++ show total ++ " is " ++ desc 
    where total = price * qty 
      desc | total < categorySize = "low" 
       | total < categorySize*2 = "medium" 
       | otherwise    = "high" 
3

问题似乎是,你需要显式转换字符串和数字。 Haskell不会自动将字符串强制转换为数字,反之亦然。

要将显示的数字转换为字符串,请使用show

要将字符串解析为数字,请使用read。由于read实际上适用于多种类型,因此您可能需要指定结果的类型,如下所示:

price :: Integer 
price = read price_input_string