我开始学习Haskell,"让你学习哈斯克尔的伟大成就!" 我犯了一个奇怪的错误,我无法找到原因.
这是我输入的代码:
let xs = [if x < 3 then "bang" else "boom" | x <- xs]
Run Code Online (Sandbox Code Playgroud)
而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"
Run Code Online (Sandbox Code Playgroud)
但是当我键入:
let boom xs = [if x < 3 then "bang" else "boom" | x <- xs]
Run Code Online (Sandbox Code Playgroud)
这是本书的例子,我没有任何问题.
有人可以解释我的错误吗?
sep*_*p2k 13
你的定义xs是递归的,就是你在xs自己的定义中使用.我不认为那是你的意图.
由于你在列表推导中使用"bang"和"boom"内部,Haskell知道xs必须是一个字符串列表(因为xs它等于列表推导的结果).此外,你说这x是xs(x <- xs)的元素,所以x必须是一个字符串(又名[Char]).不过你这样做x < 3,这意味着这x是一个数字.错误消息表示"字符串不是数字".
尝试给表达式一个类型.
xs = [if x < 3 then "bang" else "boom" | x <- xs]
Run Code Online (Sandbox Code Playgroud)
所以xs是一个列表,我们还不知道它的元素有什么类型,所以让我们看看下一个.列表元素是
if x < 3 then "bang" else "boom"
Run Code Online (Sandbox Code Playgroud)
这是类型String(aka [Char])的表达式.
所以xs :: [String].由于x来自描述列表元素的表达式是从列表xs本身中获取的,因此它String也是,并且在比较中使用
if x < 3
Run Code Online (Sandbox Code Playgroud)
现在,3是一个整数文字,因此它是多态的并且有类型
3 :: Num a => a
Run Code Online (Sandbox Code Playgroud)
所以从表达来看x < 3,我们有
Num来自文字的约束,String来自s x列表的事实的类型String.因此,我们需要一个Num实例String来获得一个良好类型的表达式.
通常,没有Num实例String(有用的是什么样的?),因此您会遇到类型错误.
如果xs是函数的参数,
boom xs = [if x < 3 then "bang" else "boom" | x <- xs]
Run Code Online (Sandbox Code Playgroud)
没有理由为什么x应该这样String,因此这是有效的.
| 归档时间: |
|
| 查看次数: |
390 次 |
| 最近记录: |