6

I'm trying to figure out how to negate the results of two parameter boolean function like not . any. I understand why it didn't work by breaking it down as shown below, but I'm not sure how to write a function that does this elegantly. I managed to do curry $ not . uncurry any

Prelude> :t not
not :: Bool -> Bool

Prelude> :t any
any :: Foldable t => (a -> Bool) -> t a -> Bool

Prelude> :t (.)
(.) :: (b -> c) -> (a -> b) -> a -> c

curry $ not . uncurry any
:: Foldable t => (a -> Bool) -> t a -> Bool
ssh
  • 195
  • 1
  • 11

3 Answers3

13

There is a standard point-free-ifier, available standalone or via lambdabot, which gives:

18:02 <dmwit> ?pl \f xs -> any (\x -> not (f x)) xs
18:02 <lambdabot> any . (not .)
18:04 <dmwit> ?pl \f xs -> not (any f xs)
18:04 <lambdabot> (not .) . any

There are many ways to spell this general operation.

Edit: Thanks to zudov for the following suggested extra text: You can also access pointfree tool by installing pointfree or using one of web interfaces (e.g. http://pointfree.io).

Community
  • 1
  • 1
Daniel Wagner
  • 145,880
  • 9
  • 220
  • 380
6

Define

result = (.)
argument = flip (.)

Then you want

(result.result) not any

i.e., negating the second result of any.

(It's also

argument (result not) all

i.e., negate the predicate then pass it into all).

See http://conal.net/blog/posts/semantic-editor-combinators

Jonathan Cast
  • 4,569
  • 19
  • 34
  • 2
    Is `(result.result) = (.).(.)` the "boob operator"? Just trying to consolidate my knowledge. – ssh Apr 24 '15 at 12:55
5
(.:) :: (r -> z) -> (a -> b -> r) -> a -> b -> z
(f .: g) x y = f (g x y)

foo :: (a -> Bool) -> [a] -> Bool
foo = not .: any

.: is also available in Data.Composition from the composition package.

Tom Ellis
  • 9,224
  • 1
  • 29
  • 54
  • Nice! May I ask how did you find this function? I initially searched for `(a -> b) -> (c -> d -> a) -> c -> d -> b` on Hoogle but I didn't find anything. – ssh Apr 24 '15 at 12:59
  • You can find it on [FP Complete's Hoogle](https://www.fpcomplete.com/hoogle?q=%28a+-%3E+b%29+-%3E+%28c+-%3E+d+-%3E+a%29+-%3E+c+-%3E+d+-%3E+b&env=ghc-7.8-stable-14.09). The haskell.org Hoogle searches a smaller set of packages by default. – Tom Ellis Apr 26 '15 at 11:29