Haskell中的函数定义

时间:2013-04-07 20:27:33

标签: function haskell

我开始学习Haskell,“让你学习哈斯克尔的伟大成就!”我犯了一个奇怪的错误,我无法找到原因。

以下是我输入的代码:

let xs = [if x < 3 then "bang" else "boom" | x <- xs]

GHCi中的错误文本:

No instance for (Num [Char])
arising from the literal `3'
Possible fix: add an instance declaration for (Num [Char])
In the second argument of `(<)', namely `(3)'
In the expression: x < (3)
In the expression: if x < (3) then "bang" else "boom"

但是当我输入时:

let boom xs = [if x < 3 then "bang" else "boom" | x <- xs]

这是本书的例子,我没有任何问题。

有人可以解释我的错误吗?

3 个答案:

答案 0 :(得分:13)

您对xs的定义是递归的,即您在其自己的定义中使用xs。我认为这不是你想要的。

由于您在列表推导中使用"bang""boom",Haskell知道xs必须是字符串列表(因为xs等于结果列表理解)。此外,您说xxsx <- xs)的元素,因此x必须是字符串(a.k.a。[Char])。但是你做x < 3,这意味着x是一个数字。错误消息表示“字符串不是数字”。

答案 1 :(得分:7)

尝试给表达式一个类型。

xs = [if x < 3 then "bang" else "boom" | x <- xs]

所以xs是一个列表,我们还不知道它的元素有什么类型,所以让我们看看下一个。列表元素是

if x < 3 then "bang" else "boom"

String类型的表达式(又名[Char])。

所以xs :: [String]。由于描述列表元素的表达式中的x取自列表xs本身,因此它也是String,用于比较

if x < 3

现在,3是一个整数文字,因此它是多态的,类型为

3 :: Num a => a

所以从表达式x < 3来看,我们有

  • 来自文字的Num约束,
  • String类型x来自String s列表中的Num

因此,我们需要一个String Num实例才能拥有一个类型良好的表达式。

通常,String没有xs个实例(有用的是什么样的?),因此会出现类型错误。

如果boom xs = [if x < 3 then "bang" else "boom" | x <- xs] 是函数的参数,

x

没有理由认为String的类型应为{{1}},因此可行。

答案 2 :(得分:0)

let xs = ... 

表示xs等于“bang”和/或“boom”的列表,但是条件指出那些元素应该测试为&lt; 3,这通常用数字而不是字符串来完成。

let boom xs =...

将函数“boom”等同于等式的右边,其中参数'xs'是从中绘制要测试的元素&lt; 3的列表。