Sind diese beiden combinators bereits in Haskell?
-
18-09-2019 - |
Frage
Ich brauche binären combinators des Typs
(a -> Bool) -> (a -> Bool) -> a -> Bool
oder vielleicht
[a -> Bool] -> a -> Bool
(obwohl dies nur der foldr1 der ersten sein würde, und ich brauche in der Regel nur zwei Booleschen Funktionen zu kombinieren.)
Ist dieser Einbau-?
Wenn nicht, die Umsetzung ist einfach:
both f g x = f x && g x
either f g x = f x || g x
oder vielleicht
allF fs x = foldr (\ f b -> b && f x) True fs
anyF fs x = foldr (\ f b -> b || f x) False fs
Hoogle taucht nichts, aber manchmal seine Suche nicht richtig verallgemeinern. Jede Idee, wenn diese eingebaut sind? Können sie aus Stücken einer bestehenden Bibliothek gebaut werden?
Wenn diese nicht eingebaut sind, können Sie neue Namen vermuten lassen, weil diese Namen ziemlich schlecht sind. In der Tat, dass der Hauptgrund ist, hoffe ich, dass sie sind eingebaut.
Lösung
Control.Monad
definiert eine 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
Sie könnten das gleiche tun mit Control.Applicative.liftA2
.
Nicht ernsthaft vorschlagen, aber ...
ghci> :t (. flip ($)) . flip all (. flip ($)) . flip all :: [a -> Bool] -> a -> Bool ghci> :t (. flip ($)) . flip any (. flip ($)) . flip any :: [a -> Bool] -> a -> Bool
Andere Tipps
Es ist kein builtin, aber die Alternative, die ich bevorzugen ist, um Typ-Klassen auf verallgemeinern die Boolesche Operationen auf Prädikate aller 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)
Ich liebe Haskell!
Ich weiß nicht, builtins, aber Ich mag die Namen vorschlagen.
getCoolNumbers = filter $ either even (< 42)
Alternativ könnte man denken eines Bedieners Symbol zusätzlich für Alternativen typeclasses.
getCoolNumbers = filter $ even <|> (< 42)