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.

War es hilfreich?

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)
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top