Function elem is throwing errors - haskell

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.

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

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

Related

How does fold distinguish x from xs in Haskell?

sum' :: (Num a) => [a] -> a
sum' xs = foldl (\acc x -> acc + x) 0 xs
There is no pattern like x:xs. xs is a list. In the lambda function, how does the expression acc + x knows that x is the element in xs?
There is no pattern like x:xs. xs is a list. In the lambda function, how does the expression acc + x knows that x is the element in xs?
In Haskell - like in many programming languages - the name of a variable does not matter. For Haskell it does not matter if you write xs, or x, or acc, or use another identifier. What matters here is actually the position of the arguments.
The foldl :: (a -> b -> a) -> a -> [b] -> a is a function that takes as input a function with type a -> b -> a, followed by an object of type a, followed by a list of elements of type b, and returns an object of type a.
Semantically the second parameter of the function, will be the elements of the list. If you thus wrote \x acc -> x + acc, acc would be the eleemnts of the list, and x the accumulator.
The reason why this binds is because foldl is implemented like:
foldl f z [] = z
foldl f z (x:xs) = foldl f (f z x) xs
It thus is defined itself in Haskell, and thus binds the function to f, the initial element to z, and performs recursion to eventually obtain the result by making a recurslive call where we take the tail of the list, and use (f z x) as new initial value until the list is exhausted.
You can write the sum more elegant as:
sum' :: Num n => [n] -> n
sum' = foldl (+) 0
so here there are no explicit variables in use at all.
It doesn't "know" anything like that - there's no magic going on here.
The definition of foldl is equivalent to:
foldl f acc (x:xs) = foldl f (f acc x) xs
foldl _ acc [] = acc
So going through a simple example using your sum' function:
We start with
sum' [1,2,3]
substituting the definition of sum' we get
foldl (\acc x -> acc + x) 0 [1,2,3]
substituting the definition of foldl (first case):
foldl (\acc x -> acc + x) ((\acc x -> acc + x) 0 1) [2,3]
evaluation the function application of your lambda, we get
foldl (\acc x -> acc + x) (0 + 1) [2,3]
substituting foldl again...
foldl (\acc x -> acc + x) ((\acc x -> acc + x) (0+1) 2) [3]
and evaluating the accumulator:
foldl (\acc x -> acc + x) ((0 + 1) + 2) [3]
and substituting foldl again...
foldl (\acc x -> acc + x) ((\acc x -> acc + x) ((0 + 1) + 2) 3) []
again, evaluating the accumulator:
foldl (\acc x -> acc + x) (((0 + 1) + 2) + 3) []
now we get to the second (terminating) case of foldl because we apply it to an empty list and are left with only:
(((0 + 1) + 2 ) + 3)
which we can of course evaluate to get 6.
As you can see, there's no magic involved here: x is just a name you gave to a function argument. You could've named it user8314628 instead and it would've worked the same way. What's binding the value of the head of the list to that argument isn't any pattern matching you do yourself, but what foldl actually does with the list.
Note that you can evaluate any haskell expression using this step-by-step process; You usually won't have to, but it's useful to do this a couple of times with functions that do more-or-less complicated things and you are unfamiliar with.
how does the expression acc + x knows that x is the element in xs?
It doesn't. It computes a sum of whatever is passed to it.
Note that (\acc x -> acc + x) can be written simply as (+).
Folds take each consecutive values of the input list while making passing the remainder back to a function transparent. If you were to write your own sum’ function, you would have to pass the remainder back to your function. You would also have to pass an accumulator back to your own function to keep a running total. Fold does not make explicit the processing of a list by taking the first value and passing the remainder. What it does explicate is the accumulator. It does also have to keep a running total in the case of a sum function. The accumulator is explicit because some recursive functions may do different things with it.

Is there a way to predict infix function behavior for partially applied functions in Haskell?

I have two functions--
partialSubtractionWith5 :: (Num a) => a -> a
partialSubtractionWith5 = (subtract 5)
and
partialSubtractionWith5' :: (Num a) => a-> a
partialSubtractionwith5' = (`subtract` 5)
calling partialSubtractionWith5 x returns the equivalent of x - 5, while calling partialSubtractionWith5' x returns the equivalent of 5 - x.
In Learn You a Haskell, Lipovača defines the following function--
isUpperAlphanum :: Char -> Bool
isUpperAlphanum = (`elem` ['A'..'B'])
Which (based on my experiments with subtract) I would have thought would have behaved like so when called as isUpperAlphanum 'some char':
Prelude> ['A'..'B'] `elem` 'some char'
False
Clearly, this is not the case. But why? And is there a way to predict what functions will reverse their arguments when partially applied?
There is no contradiction, it's just that subtract = flip (-). I.e.
partialSubtractionWith5' x ≡ (`subtract` 5) x
≡ x `subtract` 5
≡ 5 - x
and, likewise,
isUpperAlphanum '□' ≡ '□' `elem` ['A'..'B']
OTOH,
partialSubtractionWith5 x ≡ (subtract 5) x
≡ (5`subtract`) x
≡ 5 `subtract` x
≡ x - 5

Why does this point free definition not work in Haskell?

I tried to make the following function definition:
relativelyPrime x y = gcd x y == 1
point-free:
relativelyPrime = (== 1) . gcd
However, this gives me the following error:
Couldn't match type ‘Bool’ with ‘a -> Bool’
Expected type: (a -> a) -> a -> Bool
Actual type: (a -> a) -> Bool
Relevant bindings include
relativelyPrime :: a -> a -> Bool (bound at 1.hs:20:1)
In the first argument of ‘(.)’, namely ‘(== 1)’
In the expression: (== 1) . gcd
In an equation for ‘relativelyPrime’:
relativelyPrime = (== 1) . gcd
I don't quite understand. gcd takes two Ints/Integer, returns one Ints/Integer, then that one Int/Integer is checked for equality to '1'. I don't see where my error is.
It doesn't work because gcd requires two inputs whereas function composition only provides gcd one input. Consider the definition of function composition:
f . g = \x -> f (g x)
Hence, the expression (== 1) . gcd is equivalent to:
\x -> (== 1) (gcd x)
This is not what you want. You want:
\x y -> (== 1) (gcd x y)
You could define a new operator to compose a unary function with a binary function:
f .: g = \x y -> f (g x y)
Then, your expression becomes:
relativelyPrime = (== 1) .: gcd
In fact, the (.:) operator can be defined in terms of function composition:
(.:) = (.) . (.)
It looks kind of like an owl, but they are indeed equivalent. Thus, another way to write the expression:
relativelyPrime = ((== 1) .) . gcd
If you want to understand what's happening then see: What does (f .) . g mean in Haskell?
as you commented on it - if you really want a point-free version you can first use uncurry gcd to transform gcd into a version that accepts a single input (a tuple):
Prelude> :t uncurry gcd
uncurry gcd :: Integral c => (c, c) -> c
then check with (== 1) and finally curry it again for the original signature:
relativeelyPrime = curry ((== 1) . (uncurry gcd))
your version did not work just because gcd produces a function if given only the first argument and this is no legal input for (== 1) which awaits a number.

Filtering on a List of Tuples

I'm trying to filter a list of 2-tuples where the first tuple value equals 0:
ghci> ys
[(0,55),(1,100)]
ghci> filter (\x -> x.fst == 0) ys
<interactive>:71:27:
Couldn't match type `(Integer, Integer)' with `b0 -> c0'
Expected type: [b0 -> c0]
Actual type: [(Integer, Integer)]
In the second argument of `filter', namely `ys'
In the expression: filter (\ x -> x . fst == 0) ys
In an equation for `it': it = filter (\ x -> x . fst == 0) ys
My desired output:
[(1,100)]
How can I achieve this? Also, what does the compile-time error mean?
(.) is function composition, you want filter (\x -> fst x == 0) ys.
Edit: you actually want filter (\x -> fst x /= 0) ys because filter provides a list of values that satisfy the predicate.
The compile time error is complaining because the compiler infers that x must be a function because you're composing it with fst, but ys is not a list of functions.

Guards and concatiating to lists in an anonymous function

I am trying to wrap my head around the syntax of Haskell.
This problem is very simple to solve logically. I have to break up a list of positive and negative integers and group them such that
[1,2,3,-1,-2,-3,1,2,3] becomes [[1,2,3],[-1,-2,-3], [1,2,3]]
I would like to use a higher order function, foldr to be able to do that with an anonymous function taking in two arguements.
This is what I have so far.
split = foldr (\ x y -> if (x > 0)
then if (head (head y)) < 0
then [x] : y
else x : head y --error here
else if (x < 0)
then if (head (head y)) > 0
then [x] : y
else x : head y
else y
)
[[]]
this is the error i get
Occurs check: cannot construct the infinite type: a0 = [a0]
In the first argument of `(:)', namely `x'
In the expression: x : head y
In the expression:
if (head (head y)) < 0 then [x] : y else x : head y
I have two questions.
1) Why am I getting a type error at line 7?
Am I not concatenation an integer (x) to a list of integers (head y)
2) How do you write the conditions out using guards? I tried doing it but I kept getting parsing error at '|'
A function can have only one concrete return type and [x] : y is a different type from x : head y.
It's probably easier to write it with takeWhile and dropWhile:
split l = split' (if head l > 0 then (>) else (<)) l
where split' op [] = []
split' op l = takeWhile (`op` 0) l : split (dropWhile (`op` 0) l)
You're simply missing to keep tail y. In
foldr (\ x y -> if (x > 0)
then if (head (head y)) < 0
then [x] : y
else x : head y
you have x :: (Num a, Ord a) => a, y :: (Num a, Ord a) => [[a]], and head y :: (Num a, Ord a) => [a].
So forgetting the tail y shaves off one layer of []. the else branch should be
else (x:head y) : tail y
in both branches of the outer if.
But, your function has two semantic problems after that.
First, you don't treat the case that head y is empty, that will cause an exception when the end of the list is reached, and second, it doesn't work on infinite lists, since the combinator function doesn't construct anything of the result before its second argument is known. If the latter is a problem, you can find a sufficiently lazy combinator function in this answer.

Resources