Domanda

Ho bisogno combinatori binari del tipo

(a -> Bool) -> (a -> Bool) -> a -> Bool

o forse

[a -> Bool] -> a -> Bool

(anche se questo potrebbe essere solo la foldr1 del primo, e di solito solo bisogno di combinare due funzioni booleane.)

Sono questi built-in?


In caso contrario, l'applicazione è semplice:

both f g x = f x && g x
either f g x = f x || g x

o forse

allF fs x = foldr (\ f b -> b && f x) True fs
anyF fs x = foldr (\ f b -> b || f x) False fs

Hoogle salta fuori nulla, ma a volte la sua ricerca non generalizzare correttamente. Qualsiasi idea se questi sono built-in? Possono essere costruite da pezzi di una libreria esistente?

Se questi non sono built-in, si potrebbe suggerire nuovi nomi, perché questi nomi sono piuttosto male. In realtà questo è il motivo principale Spero che sono built-in.

È stato utile?

Soluzione

Control.Monad definisce un instance Monad ((->) r), così

ghci> :m Control.Monad
ghci> :t liftM2 (&&)
liftM2 (&&) :: (Monad m) => m Bool -> m Bool -> m Bool
ghci> liftM2 (&&) (5 <) (< 10) 8
True

Si potrebbe fare lo stesso con Control.Applicative.liftA2.


Non per suggerire sul serio, ma ...

ghci> :t (. flip ($)) . flip all
(. flip ($)) . flip all :: [a -> Bool] -> a -> Bool
ghci> :t (. flip ($)) . flip any
(. flip ($)) . flip any :: [a -> Bool] -> a -> Bool

Altri suggerimenti

Non è un incorporato, ma l'alternativa preferisco è quello di utilizzare le classi di tipo generalizzare le operazioni booleane per predicati di qualsiasi arità:

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)

Amo Haskell!

Non so comandi incorporati, ma mi piacciono i nomi che proponi.

getCoolNumbers = filter $ either even (< 42)

In alternativa, si potrebbe pensare ad un simbolo dell'operatore oltre a typeclasses di alternative.

getCoolNumbers = filter $ even <|> (< 42)
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top