2016-07-22 88 views
1

我的Haskell代码如下所示功能ELEM抛出错误

isNotPrime x = elem 0 map (mod x)[3.. (x-1)]  

在编译时就说明这些错误

Couldn't match expected type ‘(t1 -> t1) -> [t1] -> t’ 
       with actual type ‘Bool’ 
    The function ‘elem’ is applied to four arguments, 
    but its type ‘([a0] -> [b0]) 
       -> ((a0 -> b0) -> [a0] -> [b0]) -> Bool’ 
    has only two 
    In the expression: elem 0 map (mod x) [3 .. (x - 1)] 
    In an equation for ‘prime’: 
     prime x = elem 0 map (mod x) [3 .. (x - 1)] 

我的理解是,ELEM接受两个参数,我不明白我怎么在上面的代码中传递4个参数,因为map函数应该只返回一个列表。

回答

8

将四个参数传递给elem函数。功能应用总是关联左边,这样的表达

f a b c d 

被解析如下:

((((f a) b) c) d) 

因此,你的例子是越来越解析如下:

((((elem 0) map) (mod x)) [3.. (x-1)]) 

也就是说,elem是被“应用于四个参数”,但当然所有的Haskell函数实际上只是一个参数的函数,只是curried。你实际上想要的是一个不同的分组,所以你只需要添加一些括号:

elem 0 (map (mod x) [3.. (x-1)]) 

或者,你可以use $ to avoid writing the parentheses

elem 0 $ map (mod x) [3.. (x-1)] 

或者你可以写elem缀,这是一个Haskell中常见的成语。像$,这也会改变优先级为你想要的:

0 `elem` map (mod x) [3.. (x-1)] 
+0

很好的解释!谢谢。这工作。 – rt88

2

您传递的四个参数是0,map,mod x[3.. (x-1)]。您打算将mod x[3.. (x-1)]作为参数传递给map,然后将结果作为第二个参数传递给elem,但Haskell无法知道没有括号或$。因此,为了使你的代码工作将它们添加:

isNotPrime x = elem 0 (map (mod x) [3.. (x-1)]) 
-- or 
isNotPrime x = elem 0 $ map (mod x) [3.. (x-1)] 

或者你可以使用中缀表示法,在这种情况下,优先规则(前缀功能应用的优先级比任何管道符更紧)消除了括号的需要:

isNotPrime x = 0 `elem` map (mod x) [3.. (x-1)] 
+0

当然!这工作。谢谢:D – rt88