2013-10-16 5 views
24

A, 아마도 B 그리고 분명히 그 중 하나가 포함 된 데이터 구조가 필요합니다. 이 데이터 형식을 일반 데이터 형식으로 해킹하면 다음과 같이 표시됩니다."하나 또는 둘 다"에 대해 표준 haskell 유형이 있습니까?

data OneOrBoth a b = A a | B b | AB a b 

maybeA :: OneOrBoth a b -> Maybe a 
maybeB :: OneOrBoth a b -> Maybe b 
eitherL :: OneOrBoth a b -> Either a b -- Prefers a 
eitherR :: OneOrBoth a b -> Either a b -- Prefers b 
hasBoth, hasExactlyOne, hasA, hasB :: OneOrBoth a b -> Bool 

이 데이터 구조에 이름이 있습니까? 하스켈에서 한쪽 또는 양쪽 구조를 처리 할 표준 방법이 있습니까?

+0

이유는 두 가지 유형에서 중지 :

module Some ( Some(), this, that, those, some, oror, orro, roro, roor, swap ) where import Control.Applicative ((<|>)) newtype Some a b = Some (Maybe a, Maybe b) deriving (Show, Eq) -- smart constructors this :: a -> Some a b this a = Some (Just a,Nothing) that :: b -> Some a b that b = Some (Nothing, Just b) those :: a -> b -> Some a b those a b = Some (Just a, Just b) -- catamorphism/smart deconstructor some :: (a -> r) -> (b -> r) -> (a -> b -> r) -> Some a b -> r some f _ _ (Some (Just a, Nothing)) = f a some _ g _ (Some (Nothing, Just b)) = g b some _ _ h (Some (Just a, Just b)) = h a b some _ _ _ _ = error "this case should be unreachable due to smart constructors" swap :: Some a b -> Some b a swap ~(Some ~(ma,mb)) = Some (mb,ma) -- combining operators oror, orro, roro, roor :: Some a b -> Some a b -> Some a b -- prefer the leftmost A and the leftmost B oror (Some (ma,mb)) (Some (ma',mb')) = Some (ma <|> ma', mb <|> mb') -- prefer the leftmost A and the rightmost B orro (Some (ma,mb)) (Some (ma',mb')) = Some (ma <|> ma', mb' <|> mb) -- prefer the rightmost A and the rightmost B roro = flip oror -- prefer the rightmost A and the leftmost B roor = flip orro 

결합 운영자는 재미? 삼 사, ...? :-) –

+12

"1, A + B + A * B = (1 + A) * (1 + B)'또는'(어쩌면 A, 아마 B)'. – rampion

답변

42

Data.These

이 어느 입력이 있으면 조합 정의 두 값의 조합을 나타내는 것이 유용 할 수있다. 대수적으로 유형 은 합계 및 제품에 쉽게 포함되지 않는 (A + B + AB)를 나타냅니다. Either A (B, Maybe A)과 같은 유형은 불분명하고 은 사용하기가 불편합니다.

+3

이 패키지에는 많은 의존성과 엑스트라가 포함되어 있지만 OP에만 유용 할 수도 있고 유용하지 않을 수도 있지만 실제로 표준적인 것은 아니지만 확실히 자신 만의 롤링보다 나은 선택입니다. – bheklilr

+4

모든 경우. 그것은 OP가 이것을 많이 사용하는 것처럼 들리지만 이것이 작은 것이라면 나는 profunctors, mtl, semigroups 등에 대한 의존성을 끌어 들이고 싶지 않을 것입니다. – jozefg

+15

기사 뒤에 명명 된 고유 명사에 대해 이야기하는 것이 얼마나 어려운지 즐겁습니다. , 나는''Acme.Whose' (https://github.com/tel/acme-whose/)라는 글을 썼다.''엄격한 '과'bifunctors '만을 끌어들이는 확실한 이점이있다. 사용하지 마십시오. –

6

Data.These 언급, 아마도 최선의 선택,하지만 난 내 자신의 롤한다면, 나는 그것을 할 거라고하고있다 : 당신이 "제로를 원한다면,

import Control.Applicative ((<$>), (<*>)) 

type These a b = Either (Either a b) (a, b) 

maybeA :: These a b -> Maybe a 
maybeA (Left (Left a)) = Just a 
maybeA (Right (a, _)) = Just a 
maybeA _    = Nothing 

maybeB :: These a b -> Maybe b 
maybeB (Left (Right b)) = Just b 
maybeB (Right (_, b)) = Just b 
maybeB _    = Nothing 

eitherA :: These a b -> Either a b 
eitherA (Left (Left a)) = Left a 
eitherA (Right (a, _)) = Left a 
eitherA (Left (Right b)) = Right b 

eitherB :: These a b -> Either a b 
eitherB (Left (Right b)) = Right b 
eitherB (Right (_, b)) = Right b 
eitherB (Left (Left a)) = Left a 

hasBoth, hasJustA, hasJustB, hasA, hasB :: These a b -> Bool 

hasBoth (Right _) = True 
hasBoth _   = False 

hasJustA (Left (Left _)) = True 
hasJustA _    = False 

hasJustB (Left (Right _)) = True 
hasJustB _    = False 

hasA = (||) <$> hasBoth <*> hasJustA 
hasB = (||) <$> hasBoth <*> hasJustB 
5

하나 , 또는 둘 다 "라고 말하면 1 + A + B + A*B = (1 + A) * (1 + B) 또는 (Maybe A, Maybe B)입니다.

당신은 newtype에서 (Maybe A, Maybe B) 포장 제거 스마트 생성자를 사용하여 A + B + A*B = (1+A)*(1+B)-1을 할 수있는 (Nothing,Nothing) :

λ this "red" `oror` that "blue" `oror` those "beige" "yellow" 
Some (Just "red",Just "blue") 
λ this "red" `orro` that "blue" `orro` those "beige" "yellow" 
Some (Just "red",Just "yellow") 
λ this "red" `roor` that "blue" `roor` those "beige" "yellow" 
Some (Just "beige",Just "blue") 
λ this "red" `roro` that "blue" `roro` those "beige" "yellow" 
Some (Just "beige",Just "yellow") 
+0

대수적 인수 분해 메소드가 좋지만 실제로는 자신의 sum 유형을 롤링하는 것보다 이점을 실제로 제공하는 방법을 알지 못합니다. 'newtype'을 사용하는 것은 기본적으로 isomorphic이며 이제는 패턴 일치가 사라졌습니다. – jozefg

관련 문제