
You can still use the monadic combinators, with the price of wrapping and
unwrapping in case of newtype.
newtype P a = P {unP :: a -> Bool}
liftM2'P :: (Bool -> Bool -> Bool) -> P a -> P a -> P a
liftM2'P op = (P .) . on (liftM2 op) unP
paolino
2012/7/8 Sebastián Krynski
Ok , thanks for the answers, I understand now what liftM2 does. In this case would it be silly to use combinerPred (and maybe a newType Predicate a = a -> Bool) for the sake of readability or shoud I stick with a -> Bool and liftM2?
thanks, Sebastián
2012/7/6 Brent Yorgey
On Fri, Jul 06, 2012 at 03:17:54PM -0300, Felipe Almeida Lessa wrote:
On Fri, Jul 6, 2012 at 2:11 PM, Sebastián Krynski
wrote: As I was using predicates (a -> bool) , it appeared the need for combining them with a boolean operator (bool -> bool -> bool) in order to get a new predicate combining the previous two. So I wrote my function combinerPred (see code below). While I think this is JUST ok, i'm feeling a monad in the air. So.. where is the monad?
combinerPred :: (a -> Bool) -> (a -> Bool) -> (Bool -> Bool -> Bool) -> (a -> Bool) combinerPred pred1 pred2 op = \x -> op (pred1 x) (pred2 x)
That's the `(->) a` monad:
import Control.Applicative
combinerPred :: (a -> Bool) -> (a -> Bool) -> (Bool -> Bool -> Bool) -> (a -> Bool) combinerPred pred1 pred2 op = op <$> pred1 <*> pred2
By the way, I find it more natural to make 'op' the first argument, because it is more useful to partially apply combinerPred to an operation that it is to some predicates. Also, in that case combinerPred is simply liftA2:
import Control.Applicative
combinerPred :: (Bool -> Bool -> Bool) -> (a -> Bool) -> (a -> Bool) -> (a -> Bool) combinerPred = liftA2
-Brent
_______________________________________________ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
_______________________________________________ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe