2010-02-04 43 views
8

我需要的那種類型的二元組合子這兩個組合器在Haskell中已經可用嗎?

(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

':(a - > c) - >(b - > c) - >或者b - > c'已經在'Prelude'中;選擇一個不同的名字? – ephemient 2010-02-04 18:26:46

+0

我知道,這就是爲什麼我希望有人能提出很好的選擇。 – 2010-02-04 18:38:53

回答

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 
+0

謝謝,我不知道那個例子。所以我甚至沒有嘗試'liftM2(&&)'。 – 2010-02-04 18:37:20

+2

@ephemient:fmap和。 sequence'? – yairchu 2010-02-05 02:11:02

+1

我想我會去Monoid('Any'和'All',特別是)和'mconcat'。 – jrockway 2010-02-07 00:35:56

1

我不知道builtins,但我喜歡你提出的名字。

getCoolNumbers = filter $ either even (< 42) 

或者,人們可能覺得除了操作符號類型類的替代品。

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

我不喜歡'無論'是因爲'Prelude.either'又名'Data.Either.either'。除了已經被使用,我也喜歡它們。 :) – 2010-02-04 18:36:19

+2

關於運營商:<&&>未使用,<||>僅由Parsec(根據hoogle)。所以這些可能是最好的選擇。 – 2010-02-04 18:39:46

6

這不是一個內置的,但我更喜歡另一種方法是使用類型類概括 布爾操作的任何謂詞元數:

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) 

我喜歡哈斯克爾!

+1

哦,很好,雖然錯誤信息,如果你偶然混合arities可能會*有趣*。我會傾向於調用這些'。&&。 || .'或者類似的東西:-) – ephemient 2010-02-05 20:52:32

+0

這真的很酷。很高興我偶然發現了這個!哈斯克爾從未停止驚歎:D – 2010-02-05 21:11:51

相關問題