이 두 콤비네이터는 이미 Haskell에서 사용할 수 있습니까?
-
18-09-2019 - |
문제
이 유형의 이진 조합기가 필요합니다
(a -> Bool) -> (a -> Bool) -> a -> Bool
아니면 어쩌면
[a -> Bool] -> a -> Bool
(이것은 단지 첫 번째의 폴드 드 1 일 뿐이며, 나는 보통 두 개의 부울 함수 만 결합하면됩니다.)
이 내장 되었습니까?
그렇지 않은 경우 구현은 간단합니다.
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은 아무것도 나타나지 않지만 때로는 검색이 제대로 일반화되지 않습니다. 이것들이 내장되어 있는지에 대한 아이디어가 있습니까? 기존 라이브러리 조각으로 건축 할 수 있습니까?
이것들이 내장되어 있지 않으면 새로운 이름을 제안 할 수 있습니다.이 이름은 꽤 나쁘기 때문입니다. 사실 그게 내가 그들이 그들을 희망하는 주된 이유입니다. ~이다 내장.
해결책
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
다른 팁
그것은 내장이 아니지만, 내가 선호하는 대안은 유형 클래스를 사용하는 것입니다. 부울 작전을 모든 아티브의 exticates에게 일반화하십시오.
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)
나는 Haskell을 좋아한다!
나는 BuildIns를 모르지만, 당신이 제안하는 이름을 좋아합니다.
getCoolNumbers = filter $ either even (< 42)
또는 대안을위한 전자 클래스 외에 연산자 기호를 생각할 수 있습니다.
getCoolNumbers = filter $ even <|> (< 42)
제휴하지 않습니다 StackOverflow