rt88
rt88

Reputation: 43

Function elem is throwing errors

My Haskell code is as follows

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

When compiled it shows these errors

  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)]

My understanding is that elem accepts two arguments, I do not understand how am I passing 4 arguments in the above code as the map function should just return a list.

Upvotes: 1

Views: 111

Answers (2)

Alexis King
Alexis King

Reputation: 43842

You are passing four arguments to the elem function. Function application always associates left, so the expression

f a b c d

is parsed like this:

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

Therefore, your example is getting parsed like this:

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

That is, elem is being “applied to four arguments”, but of course all Haskell functions are actually just functions of one argument, just curried. What you actually want is a different grouping, so you just need to add some parentheses:

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

Alternatively, you could use $ to avoid writing the parentheses:

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

Or you could write elem infix, which is a common idiom in Haskell. Like $, this will also change the precedence to be what you want:

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

Upvotes: 8

sepp2k
sepp2k

Reputation: 370132

The four arguments you are passing are 0, map, mod x and [3.. (x-1)]. You intended to pass mod x and [3.. (x-1)] as arguments to map and then pass the result as the second argument to elem, but there's no way for Haskell to know that without parentheses or $. So to make your code work add them:

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

Or you can use infix notation, in which case precedence rules (prefix function application binds tighter than any infix operator) removes the need for parentheses:

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

Upvotes: 2

Related Questions