[Haskell-cafe] How to make boolean logic with IO Monad more expressive?

Viktor Dukhovni ietf-dane at dukhovni.org
Mon May 27 09:46:11 UTC 2019


On Mon, May 27, 2019 at 07:37:37PM +1000, Jack Kelly wrote:

> Viktor Dukhovni <ietf-dane at dukhovni.org> writes:
> 
> >> On May 27, 2019, at 1:07 AM, Magicloud Magiclouds <magicloud.magiclouds at gmail.com> wrote:
> >> 
> >> ```
> >> status <- ioOperation -- IO-ed anyway
> >> return $ pureComputing || (status && pure2)
> >> ```
> >
> > With two helpers:
> >
> >   (<&&>) :: IO Bool -> IO Bool -> IO Bool
> >   (<&&>) ma mb = ma >>= (\a -> if not a then return False else mb)
> >
> >   (<||>) :: IO Bool -> IO Bool -> IO Bool
> >   (<||>) ma mb = ma >>= (\a -> if a then return True else mb)
> 
> These generalise to any Applicative, I think:
> 
> import Control.Applicative (liftA2)
> 
> (<&&>) = liftA2 (&&)
> (<||>) = liftA2 (||)

As written, the above Applicative version won't short-circuit (is
strict in both arguments) in the IO Monad.  For example, the below
will still read stdin:

    pure False <&&> (getLine >>= return . read)

The generalized Monadic version will short-circuit.

      (<&&>) :: Monad m => m Bool -> m Bool -> m Bool
      (<&&>) ma mb = ma >>= (\a -> if not a then return False else mb)

      (<||>) :: Monad m => m Bool -> m Bool -> m Bool
      (<||>) ma mb = ma >>= (\a -> if a then return True else mb)

-- 
	Viktor.


More information about the Haskell-Cafe mailing list