我需要
类型的二元组合子(a -> Bool) -> (a -> Bool) -> a -> Bool
或者
[a -> Bool] -> a -> Bool
(虽然这只是第一个的foldr1,我通常只需要组合两个布尔函数。)
这些都是内置的吗?
如果没有,实施很简单:
both f g x = f x && g x
either f g x = f x || g x
或者
allF fs x = foldr (\ f b -> b && f x) True fs
anyF fs x = foldr (\ f b -> b || f x) False fs
Hoogle什么都没有,但有时它的搜索没有正确概括。不知道这些是否是内置的?它们可以用现有的库来构建吗?
如果这些不是内置的,您可能会建议使用新名称,因为这些名称非常糟糕。事实上,这是我希望他们 内置的主要原因。
答案 0 :(得分:13)
Control.Monad
定义了instance Monad ((->) r)
,所以
ghci> :m Control.Monad ghci> :t liftM2 (&&) liftM2 (&&) :: (Monad m) => m Bool -> m Bool -> m Bool ghci> liftM2 (&&) (5 <) (< 10) 8 True
您可以对Control.Applicative.liftA2
执行相同操作。
不要认真地提出建议,但是......
ghci> :t (. flip ($)) . flip all (. flip ($)) . flip all :: [a -> Bool] -> a -> Bool ghci> :t (. flip ($)) . flip any (. flip ($)) . flip any :: [a -> Bool] -> a -> Bool
答案 1 :(得分:6)
它不是内置的,但我更喜欢的替代方法是使用类型类概括 对任何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)
我爱哈斯克尔!
答案 2 :(得分:1)
我不知道内置,但我喜欢你提出的名字。
getCoolNumbers = filter $ either even (< 42)
或者,除了替代类型的类型之外,还可以考虑运算符符号。
getCoolNumbers = filter $ even <|> (< 42)