代码之家  ›  专栏  ›  技术社区  ›  Nathan Shively-Sanders

这两个组合器在Haskell中是否已经可用?

  •  8
  • Nathan Shively-Sanders  · 技术社区  · 15 年前

    我需要这种类型的二进制组合符

    (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
    

    如果这些不是内置的,您可能会建议使用新名称,因为这些名称非常糟糕。事实上,这是我希望他们

    3 回复  |  直到 15 年前
        1
  •  13
  •   ephemient    15 年前

    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
    
        2
  •  6
  •   Norman Ramsey    15 年前

    它不是内置的,但我更喜欢使用类型类来 对任意算术谓词的布尔运算:

    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)
    

    我爱哈斯克尔!

        3
  •  1
  •   Dario    15 年前

    getCoolNumbers = filter $ either even (< 42)
    

    getCoolNumbers = filter $ even <|> (< 42)