0

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

1
  • Functions in Haskell are called fun arg1 arg2 ..., not fun(arg1, arg2 ...). Commented Apr 10, 2015 at 21:04

3 Answers 3

4

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 
Sign up to request clarification or add additional context in comments.

2 Comments

I think head x == f will be a type error itself ?
Fixed with my best guess of what the OP wanted.
2

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

1 Comment

A nice idiom: deleteif (x:xs) f = [x | not (f x)] ++ deleteif xs f. Also, deleteif xs f = filter (not . f) xs
2

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.

  • For one thing, it allows you to write dense statements without needing many parentheses – in fact deleteif (tail x f) could also be written deleteif $ tail x f.
  • More importantly, because the arguments don't need to be “encased” in a single tuple, you don't need to supply them all at once but automatically get partial application when you apply to only one argument. For instance, you could use this function like that: 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].

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.