Reputation: 6500
Why does the first case works OK but not the second? I believe . operator chains the function and since f returns Boolean i could "not" it, but why does it not work in the second case?
*Main> let filterNot f xs = filter (not . f) xs
*Main> let filterNot f xs = filter (not (f)) xs
Upvotes: 0
Views: 152
Reputation: 54068
This is because there is a difference between not . f
and not f
. If you want to do it without using .
, you'll have to use a lambda:
filterNot f xs = filter (\x -> not (f x)) xs
But this is precisely the definition of .
!
(.) :: (b -> c) -> (a -> b) -> (a -> c)
f . g = \x -> f (g x)
Just because f
returns a Bool
does not mean that you can not
it. You can only not
a Bool
itself, not a function that returns one. There is a large difference between a -> Bool
and just Bool
. The definition of not
is
not :: Bool -> Bool
not True = False
not False = True
So if f
itself is not True
or False
exactly, then you can't apply not
to it.
(Whew, that's a not of negatives in this explanation)
Upvotes: 9