在下面的代码片段中,您可以看到我在Haskell中编写的两个collatz函数.对于递归应用程序,我在第一个示例(collatz)中使用括号来获得正确的优先级.
由于我刚刚用$学习了函数应用程序,我试图用这个东西重写函数(collatz').但是,我遇到以下错误:
无法匹配期望类型`[a]'与推断类型`a1 - > [a1]'在`(:)'的第二个参数中,即``collatz''在`($)'的第一个参数中,即`n:collatz''在表达式中:n:collatz'$ n`div` 2
collatz :: (Integral a) => a -> [a]
collatz 1 = [1]
collatz n | even n = n : collatz (n `div` 2)
| otherwise = n : collatz (n * 3 + 1)
collatz' :: (Integral a) => a -> [a]
collatz' 1 = [1]
collatz' n | even n = n : collatz' $ n `div` 2
| otherwise = n : collatz' $ n * 3 + 1
Run Code Online (Sandbox Code Playgroud)
它对我来说很奇怪,这不起作用.所以我尝试了一个类似的例子:
True : [even $ 3 `div` 3]
Run Code Online (Sandbox Code Playgroud)
我很感激,如果有人可以看看它并告诉我我做错了什么.
hug*_*omg 18
$
具有较低的优先级:
(以及其他任何东西),因此您的函数正在解析为
(n : collatz') $ (n `div` 2)
Run Code Online (Sandbox Code Playgroud)
这会导致您的类型错误.:
期望列表的第二个参数,但您传递的是collatz函数.
如果您仍想避免3n + 1部分周围的括号,您可以执行以下操作
(n:) . collatz' $ n `div` 2
n : (collatz' $ n `div` 2)
Run Code Online (Sandbox Code Playgroud)
虽然这些不一定比原版更清洁.如果你想知道,(n:)
在第一个例子中是一个语法糖\x -> n : x
ham*_*mar 10
由于其他人已经解释了问题所在,我想我会解释你如何能够自己解决这个问题.(教一个人钓鱼等等......)
请注意错误消息的这一部分:
在'($)'的第一个参数中,即'n:collatz''
这是发现这是一个优先问题的线索.GHC告诉你,它n : collatz'
被解析为第一个参数$
,而你期望第一个参数是公正的collatz'
.
此时,我通常会启动GHCi并使用该:info
命令检查所涉及的优先级:
> :info :
data [] a = ... | a : [a] -- Defined in GHC.Types
infixr 5 :
> :info $
($) :: (a -> b) -> a -> b -- Defined in GHC.Base
infixr 0 $
Run Code Online (Sandbox Code Playgroud)
它说优先级:
是5,而优先级$
是0,这解释了为什么:
绑定"比"更严格$
.
:
结合力强于$
.考虑
Prelude> let f x = [x]
Prelude> 1 : f 2
[1,2]
Prelude> 1 : f $ 2
<interactive>:1:5:
Couldn't match expected type `[a0]' with actual type `t0 -> [t0]'
In the second argument of `(:)', namely `f'
In the expression: 1 : f
In the expression: 1 : f $ 2
Run Code Online (Sandbox Code Playgroud)
注意1 : f
解析器找到的"表达式" ; 它看到(1 : f) $ 2
而不是1 : (f $ 2)
.