为什么在这行haskell中,$无法替换()

时间:2015-09-09 15:37:39

标签: haskell

代码是

prime (x:xs) = x:prime (filter (\y -> y `mod` x /=0) xs) 

如果我将其更改为

prime (x:xs) = x:prime $ filter (\y -> y `mod` x /=0) xs

存在模式匹配错误。

3 个答案:

答案 0 :(得分:4)

如果我尝试重现错误,似乎GHC理解它是这样的:

(x : prime) $ filter (\y -> y `mod` x /= 0) xs

但你想要那样:

x : (prime $ filter (\y -> y `mod` x /= 0) xs)

我认为你必须使用括号表示法。

答案 1 :(得分:3)

首先,错误地认为$()的句法替代 - $是一个常规运算符(它本身就是一个默认为中缀的函数);它只是在许多情况下使$方便的优先规则 - 但它背后没有语法魔法。

现在,忽略不相关的位,让我们只关注导致错误的代码部分:

x :  prime (foo bar)

相同
x : (prime (foo bar))

因为左边的:的优先级低于右边的函数应用程序。

然而

x : prime   $  foo bar

相同
(x : prime) $ (foo bar)

相同
(x : prime)   (foo bar)

因为左侧的:优先级高于右侧的$

因此,错误来自于您尝试将表达式x : prime的结果应用于参数foo bar,就好像x : prime是函数一样,但事实并非如此,因此类型错误。

解决方案?要么抛出一些括号,要么更好,在这种情况下根本不使用$

答案 2 :(得分:0)

其他人已经解释了这个问题。这是一个解决方案:

prime (x:xs) = (x:) $ prime $ filter (\y -> y `mod` x /=0) xs

也就是说,您可以使用运算符部分来表达:x的应用,然后根据需要应用结果。