Reputation: 13
I am learning Haskell. I am trying to make a function that deletes integers out of a list when met with the parameters of a certain function f.
deleteif :: [Int] -> (Int -> Bool) -> [Int]
deleteif x f = if x == []
then []
else if head x == f
then deleteif((tail x) f)
else [head x] ++ deleteif((tail x) f)
I get the following errors :
function tail is applied to two arguments
'deleteif' is applied to too few arguments
Upvotes: 0
Views: 1265
Reputation: 120711
As already said, deleteif((tail x) f)
is parsed as deleteif (tail x f)
, which means tail
is applied to the two arguments x
and f
, and the result would then be passed on as the single argument to deleteif
. What you want is deleteif (tail x) f
, which is equivalent to (deleteif (tail x)) f
and what most languages1 would write deleteif(tail x, f)
.
This parsing order may seem confusing initially, but it turns out to be really useful in practice. The general name for the technique is Currying.
deleteif (tail x f)
could also be written deleteif $ tail x f
.deleteif (>4) [1,3,7,5,2,9,7]
to yield [7,5,9,7]
. This works by partially applying the function2 >
to 4
, leaving a single-argument function which can be used to filter the list.1Indeed, this style is possible in Haskell as well: just write the signatures of such multi-argument functions as deleteif :: ([Int], Int->Bool) -> [Int]
. Or write uncurry deleteif (tail x, f)
. But it's definitely better you get used to the curried style!
2Actually, >
is an infix which behaves a bit different – you can partially apply it to either side, i.e. you can also write deleteif (4>) [1,3,7,5,2,9,7]
to get [1,3,2]
.
Upvotes: 2
Reputation: 402
the problem is in deleteif((tail x) f)
it becomes deleteif (tail x f)
so tail gets 2 arguments
and then deleteif a
so deleteif gets 1 argument
you want deleteif (tail x) f
head x == f
is wrong you want `f (head x)
you can use pattern matching ,guards and make it more generic
deleteif :: [a] -> (a -> Bool) -> [a]
deleteif [] _ = []
deleteif (x:xs) f
| f x = deleteif xs f
| otherwise = x : deleteif xs f
Upvotes: 2
Reputation: 198103
The issue is that you don't use parentheses to call a function in Haskell. So you just need to use
if f (head x)
then deleteif (tail x) f
else [head x] ++ deleteif (tail x) f
Upvotes: 4