How To Negate A Function?

haskell

Solution

There is actually a `not` function for booleans, but as always you have to get the types right. Say your existing functions have the following type:

ascending :: (Ord a) => [a] -> Bool
ascending (x1:x2:xs) = x1 <= x2 && ascending (x2:xs)
ascending _ = True

descending :: (Ord a) => [a] -> Bool
descending (x1:x2:xs) = x1 >= x2 && descending (x2:xs)
descending _ = True

Requiring both means that the lists have to be equal, because that's the only way for them to be both ascending and descending in the sense I have defined above:

both xs = ascending xs && descending xs

To invert booleans there is the `not` function:

not :: Bool -> Bool

Then being neither is expressed with this function:

neither xs = not (ascending xs || descending xs)

This is, of course, the same as:

neither xs = not (ascending xs) && not (descending xs)

You can use applicative style with the reader functor to make this look a bit more pleasing:

import Control.Applicative

both    = liftA2 (&&) ascending descending
neither = not . liftA2 (||) ascending descending

Or alternatively:

neither = liftA2 (&&) (not . ascending) (not . descending)

More: This gives rise to a notion of predicates:

type Predicate a = a -> Bool

A predicate is a boolean function. The two functions `ascending` and `descending` defined above are predicates. Instead inverting booleans, you can invert predicates:

notP :: Predicate a -> Predicate a
notP = (not .)

And instead of conjunction and disjunction on booleans, we can have them on predicates, which allows writing composite predicates more nicely:

(^&^) :: Predicate a -> Predicate a -> Predicate a
(^&^) = liftA2 (&&)

(^|^) :: Predicate a -> Predicate a -> Predicate a
(^|^) = liftA2 (||)

This lets us write `both` and `neither` really nicely:

both = ascending ^&^ descending

neither = notP ascending ^&^ notP descending

The following law holds for predicates,

notP a ^&^ notP b = notP (a ^|^ b)

so we can rewrite `neither` even more nicely:

neither = notP (ascending ^|^ descending)

Problem

This might be a really dumb question but.. I have written two quick functions that check if three numbers are in descending or ascending order. IE 2 3 5 would be true for ascending and false for descending. 1 5 3 would be false for both I need to make a third function that will work by only calling these first two. I am using GHCi. This third function sees if the numbers are not in any order like the second example above So it would be like ``` let newfunction = (not)Ascending && (not)Descending ``` How do I do this though? The /= doesn't work for me

Original source