Son estos dos combinadores ya disponible en Haskell?
-
18-09-2019 - |
Pregunta
Necesito combinadores binarios del tipo
(a -> Bool) -> (a -> Bool) -> a -> Bool
o tal vez
[a -> Bool] -> a -> Bool
(aunque esto no sería más que la foldr1 de la primera, y por lo general sólo es necesario combinar dos funciones booleanas.)
Son incorporados en estas?
Si no es así, la aplicación es sencilla:
both f g x = f x && g x
either f g x = f x || g x
o tal vez
allF fs x = foldr (\ f b -> b && f x) True fs
anyF fs x = foldr (\ f b -> b || f x) False fs
Hoogle vuelve a nada, pero a veces su búsqueda no generalizar correctamente. Cualquier idea si éstos están incorporados? Pueden ser construidos a partir de piezas de una biblioteca existente?
Si estos no están incorporados, puede sugerir nuevos nombres, debido a que estos nombres son bastante malos. De hecho esa es la razón principal por la que espero que son incorporado.
Solución
Control.Monad
define un instance Monad ((->) r)
, por lo
ghci> :m Control.Monad ghci> :t liftM2 (&&) liftM2 (&&) :: (Monad m) => m Bool -> m Bool -> m Bool ghci> liftM2 (&&) (5 <) (< 10) 8 True
Se puede hacer lo mismo con Control.Applicative.liftA2
.
No sugerir serio, pero ...
ghci> :t (. flip ($)) . flip all (. flip ($)) . flip all :: [a -> Bool] -> a -> Bool ghci> :t (. flip ($)) . flip any (. flip ($)) . flip any :: [a -> Bool] -> a -> Bool
Otros consejos
No es una orden interna, pero la alternativa es que prefiero utilizar el tipo clases a generalizar las operaciones booleanas a los predicados de cualquier aridad:
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!
No sé órdenes internas, pero me gustan los nombres que usted propone.
getCoolNumbers = filter $ either even (< 42)
Como alternativa, se podría pensar en un símbolo de operador, además de clases de tipos de alternativas.
getCoolNumbers = filter $ even <|> (< 42)