Sont ces deux combinateurs déjà disponibles dans Haskell?
-
18-09-2019 - |
Question
J'ai besoin combinators binaires du type
(a -> Bool) -> (a -> Bool) -> a -> Bool
ou peut-être
[a -> Bool] -> a -> Bool
(bien que ce serait juste le foldr1 de la première, et je dois généralement combiner deux fonctions booléennes.)
Sont-ils intégrés?
Dans le cas contraire, la mise en œuvre est simple:
both f g x = f x && g x
either f g x = f x || g x
ou peut-être
allF fs x = foldr (\ f b -> b && f x) True fs
anyF fs x = foldr (\ f b -> b || f x) False fs
Hoogle se présente rien, mais parfois sa recherche ne généralise pas correctement. Toute idée si ceux-ci sont intégrés? Peuvent-ils être construits à partir de morceaux d'une bibliothèque existante?
Si ceux-ci ne sont pas intégrés, vous pouvez suggérer de nouveaux noms, parce que ces noms sont assez mauvais. En fait, c'est la principale raison pour laquelle j'espère qu'ils sont intégré.
La solution
Control.Monad
définit une instance Monad ((->) r)
, de sorte
ghci> :m Control.Monad ghci> :t liftM2 (&&) liftM2 (&&) :: (Monad m) => m Bool -> m Bool -> m Bool ghci> liftM2 (&&) (5 <) (< 10) 8 True
Vous pouvez faire la même chose avec Control.Applicative.liftA2
.
ne veut pas dire sérieusement, mais ...
ghci> :t (. flip ($)) . flip all (. flip ($)) . flip all :: [a -> Bool] -> a -> Bool ghci> :t (. flip ($)) . flip any (. flip ($)) . flip any :: [a -> Bool] -> a -> Bool
Autres conseils
Il est pas une commande interne, mais l'alternative que je préfère est d'utiliser des classes de type généralisent les opérations booléennes à prédicats d'arité quelconque:
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!
Je ne sais pas builtins, mais j'aime les noms que vous proposez.
getCoolNumbers = filter $ either even (< 42)
Alternativement, on pourrait penser à un symbole de l'opérateur, en plus de classes de types d'alternatives.
getCoolNumbers = filter $ even <|> (< 42)