Haskell报错求助:Variable not in scope: doubleMe :: [Integer] -> t
解决Haskell报错:Variable not in scope: doubleMe :: [Integer] -> t
哈哈,这个错误我当初入门Haskell的时候也踩过!别着急,咱们一步步来捋清楚问题出在哪。
错误原因拆解
这个报错的核心意思是:Haskell找不到你要调用的doubleMe函数——你肯定是跳过了函数定义的步骤,直接就去调用它了对吧?毕竟《Learn You a Haskell for Great Good》里先讲了函数的定义,才会提到嵌套调用的例子,可能你没把这部分代码写全。
先补上doubleMe的正确定义
书中的doubleMe函数是用来把列表里每个元素乘2的,有两种常见写法,你任选其一就行:
写法1:递归实现(书中大概率用的这种)
-- 先声明函数类型(可选但推荐,让代码更清晰) doubleMe :: [Integer] -> [Integer] -- 空列表的情况:返回空列表 doubleMe [] = [] -- 非空列表:取第一个元素乘2,再递归处理剩下的列表 doubleMe (x:xs) = x * 2 : doubleMe xs
写法2:列表推导式(更简洁)
doubleMe xs = [x * 2 | x <- xs]
按照正确顺序执行代码
Haskell是静态类型语言,必须先定义函数和变量,再调用它们。你需要按照以下顺序在GHCi里输入:
- 先定义列表:
xs = [1,2,3,4,5,6,7,8]
- 再定义上面的
doubleMe函数 - 最后调用嵌套的函数(注意Haskell里函数调用用空格分隔,括号用来分组,或者用
$简化嵌套):
-- 用括号分组的写法 doubleMe (doubleMe (doubleMe xs)) -- 用$简化的写法(更符合Haskell风格) doubleMe $ doubleMe $ doubleMe xs
额外小提示
别犯这个新手常见的错误:如果直接写doubleMe doubleMe doubleMe xs,Haskell会把它解析成((doubleMe doubleMe) doubleMe) xs,这显然不是你想要的——它会把doubleMe函数本身当成参数传给doubleMe,这肯定会报错。所以一定要用括号或者$来明确嵌套关系。
现在按照这个步骤来,你就能得到正确的结果啦!
内容的提问来源于stack exchange,提问作者Murphy Ho
相关产品推荐
相关产品推荐

