【问题标题】:Haskell Recursion and Type ErrorHaskell 递归和类型错误
【发布时间】:2011-02-24 12:35:52
【问题描述】:

我正在自学 Haskell,学习任何编程语言的最佳方式就是使用它。我目前的“练习”是 take 的实现。伪代码为:

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 资源是“Learn You a Haskell for Great Good!”我已经多次阅读关于类型的部分试图弄清楚这一点。谷歌也异常无益。我认为我还不完全理解打字。谁能解释发生了什么问题?

【问题讨论】:

    标签: haskell recursion types


    【解决方案1】:
    myTake n - 1 ls
    

    被解析为

    (myTake n) - (1 ls)
    

    因为函数应用程序的绑定比任何中缀运算符都高。用括号括起来:

    myTake (n - 1) ls
    

    【讨论】:

    • 谢谢,解决了。我很高兴它只是这样简单的事情。
    • 根据经验,如果作为前缀函数的参数的表达式不仅仅是一个变量名,则始终用括号括起来。
    • 请注意,这就是x : f y 起作用的原因,因为函数应用程序f y: 绑定得更紧密,所以就好像你用括号括起来了x : (f y)
    • 其实报错信息是这样的,因为:-绑定得更紧密,所以解析为(l : (myTake n)) - (1 ls)。这就是为什么它抱怨: 的第二个参数是一个函数 - myTake 只是部分应用。
    猜你喜欢
    • 1970-01-01
    • 2016-06-15
    • 2016-12-29
    • 1970-01-01
    • 1970-01-01
    • 2016-05-23
    • 1970-01-01
    • 2016-09-20
    • 1970-01-01
    相关资源
    最近更新 更多