Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

In Haskell performing `and` and `or` for boolean functions

I just wrote the following two functions:

fand :: (a -> Bool) -> (a -> Bool) -> a -> Bool fand f1 f2 x = (f1 x) && (f2 x)  f_or :: (a -> Bool) -> (a -> Bool) -> a -> Bool f_or f1 f2 x = (f1 x) || (f2 x) 

They might be used to combined the values of two boolean functions such as:

import Text.ParserCombinators.Parsec import Data.Char  nameChar = satisfy (isLetter `f_or` isDigit) 

After looking at these two functions, I came to the realization that they are very useful. so much so that I now suspect that they are either included in the standard library, or more likely that there is a clean way to do this using existing functions.

What was the "right" way to do this?

like image 287
John F. Miller Avatar asked Apr 18 '11 23:04

John F. Miller


People also ask

What is && in Haskell?

The Haskell Report gives a full listing of the Prelude which serves as a spec. And it's perfectly alright to care about this, since (&&) can be used to combine a simple & quick test with one that requires intensive computation.

How do you do or in Haskell?

Or operator is represented by using the '||' double pipe symbol in Haskell. Also, it is an in-built operator available in Haskell, we don't require to include anything to use this while programming.

How do you define Boolean in Haskell?

Description: The boolean type Bool is an enumeration. The basic boolean functions are (&&) (and), (||) (or), and not. The name is defined as True to make guarded expressions more readable.

What does == mean in Haskell?

The == is an operator for comparing if two things are equal. It is quite normal haskell function with type "Eq a => a -> a -> Bool". The type tells that it works on every type of a value that implements Eq typeclass, so it is kind of overloaded.


2 Answers

One simplification,

f_and = liftM2 (&&) f_or  = liftM2 (||) 

or

      = liftA2 (&&)                = liftA2 (||) 

in the ((->) r) applicative functor.


Applicative version

Why? We have:

instance Applicative ((->) a) where     (<*>) f g x = f x (g x)  liftA2 f a b = f <$> a <*> b  (<$>) = fmap  instance Functor ((->) r) where     fmap = (.) 

So:

  \f g -> liftA2 (&&) f g = \f g -> (&&) <$> f <*> g          -- defn of liftA2 = \f g -> ((&&) . f) <*> g          -- defn of <$> = \f g x -> (((&&) . f) x) (g x)    -- defn of <*> - (.) f g = \x -> f (g x) = \f g x -> ((&&) (f x)) (g x)      -- defn of (.) = \f g x -> (f x) && (g x)          -- infix (&&) 

Monad version

Or for liftM2, we have:

instance Monad ((->) r) where     return = const     f >>= k = \ r -> k (f r) r 

so:

  \f g -> liftM2 (&&) f g = \f g -> do { x1 <- f; x2 <- g; return ((&&) x1 x2) }               -- defn of liftM2 = \f g -> f >>= \x1 -> g >>= \x2 -> return ((&&) x1 x2)              -- by do notation = \f g -> (\r -> (\x1 -> g >>= \x2 -> return ((&&) x1 x2)) (f r) r)  -- defn of (>>=) = \f g -> (\r -> (\x1 -> g >>= \x2 -> const ((&&) x1 x2)) (f r) r)   -- defn of return = \f g -> (\r -> (\x1 ->                (\r -> (\x2 -> const ((&&) x1 x2)) (g r) r)) (f r) r) -- defn of (>>=) = \f g x -> (\r -> (\x2 -> const ((&&) (f x) x2)) (g r) r) x         -- beta reduce = \f g x -> (\x2 -> const ((&&) (f x) x2)) (g x) x                   -- beta reduce = \f g x -> const ((&&) (f x) (g x)) x                               -- beta reduce = \f g x -> ((&&) (f x) (g x))                                       -- defn of const = \f g x -> (f x) && (g x)                                           -- inline (&&) 
like image 63
Don Stewart Avatar answered Sep 20 '22 18:09

Don Stewart


Totally ripping off of TomMD, I saw the and . map and or . map and couldn't help but want to tweak it:

fAnd fs x = all ($x) fs fOr fs x = any ($x) fs 

These read nicely I think. fAnd: are all functions in the list True when x is applied to them? fOr: are any functions in the list True when x is applied to them?

ghci> fAnd [even, odd] 3 False ghci> fOr [even, odd] 3 True 

fOr is an odd name choice, though. Certainly a good one to throw those imperative programmers for a loop. =)

like image 30
Dan Burton Avatar answered Sep 21 '22 18:09

Dan Burton