Are these two combinators already available in Haskell?
I need binary combinators of the type
(a -> Bool) -> (a -> Bool) -> a -> Bool
or maybe
[a -> Bool] -> a -> Bool
(though this would just be the foldr1 of the first, and I usually only need to combine two boolean functions.)
Are these built-in?
If not, the implementation is simple:
both f g x = f x && g x
either f g x = f x || g x
开发者_如何学Python
or perhaps
allF fs x = foldr (\ f b -> b && f x) True fs
anyF fs x = foldr (\ f b -> b || f x) False fs
Hoogle turns up nothing, but sometimes its search doesn't generalise properly. Any idea if these are built-in? Can they be built from pieces of an existing library?
If these aren't built-in, you might suggest new names, because these names are pretty bad. In fact that's the main reason I hope that they are built-in.
Control.Monad
defines an instance Monad ((->) r)
, so
ghci> :m Control.Monad ghci> :t liftM2 (&&) liftM2 (&&) :: (Monad m) => m Bool -> m Bool -> m Bool ghci> liftM2 (&&) (5 <) (< 10) 8 True
You could do the same with Control.Applicative.liftA2
.
Not to seriously suggest it, but...
ghci> :t (. flip ($)) . flip all (. flip ($)) . flip all :: [a -> Bool] -> a -> Bool ghci> :t (. flip ($)) . flip any (. flip ($)) . flip any :: [a -> Bool] -> a -> Bool
It's not a builtin, but the alternative I prefer is to use type classes to generalize the Boolean operations to predicates of any arity:
module Pred2 where
class Predicate a where
complement :: a -> a
disjoin :: a -> a -> a
conjoin :: a -> a -> a
instance Predicate Bool where
complement = not
disjoin = (||)
conjoin = (&&)
instance (Predicate b) => Predicate (a -> b) where
complement = (complement .)
disjoin f g x = f x `disjoin` g x
conjoin f g x = f x `conjoin` g x
-- examples:
ge :: Ord a => a -> a -> Bool
ge = complement (<)
pos = (>0)
nonzero = pos `disjoin` (pos . negate)
zero = complement pos `conjoin` complement (pos . negate)
I love Haskell!
I don't know builtins, but I like the names you propose.
getCoolNumbers = filter $ either even (< 42)
Alternately, one could think of an operator symbol in addition to typeclasses for alternatives.
getCoolNumbers = filter $ even <|> (< 42)
精彩评论