2011-02-24 71 views
3

我在教自己Haskell和学习任何编程语言的最好方法就是使用它。我目前的“练习”是take的实现。伪代码是:Haskell递归和类型错误

take(0, list) = [] --empty list 
take(n, list) = const(head(list), take(n-1, tail(list)) 

我一直在Haskell制定是:

myTake :: (Num a) => a -> [b] -> [b] 
myTake 0 l = [] 
myTake n (l:ls) = l : myTake n-1 ls 

,当我在GHCI加载的文件这不编译。这是我得到的错误消息:

Couldn't match expected type `[b]' 
     against inferred type `[b1] -> [b1]' 
In the second argument of `(:)', namely `myTake n - 1 ls' 
In the expression: l : myTake n - 1 ls 
In the definition of `myTake': 
    myTake n (l : ls) = l : myTake n - 1 ls 

我当前的Haskell资源是“学习你一个好主意的Haskell!”我已经多次阅读关于类型的章节,试图弄清楚这一点。谷歌也非常无用。我认为我还没有完全理解打字。任何人都可以解释发生了什么问题?

回答

7
myTake n - 1 ls 

被解析等

(myTake n) - (1 ls) 

因为功能应用程序绑定比任何缀运算符更高。括号内:

myTake (n - 1) ls 
+0

谢谢,解决了它。我很高兴这只是一个简单的事情。 – 2011-02-24 04:40:58

+1

作为一个经验法则,如果它们不仅仅是一个变量名称,则总是将括号表达式作为前缀函数的参数。 – fuz 2011-02-24 18:29:13

+1

注意这就是为什么'x:fy'可以工作的原因,因为函数应用程序'fy'比':'绑定的更紧密,所以就好像你使用了括号'x:(fy)' – 2011-02-24 21:06:12