2016-10-21 12 views
2

두 개의 매개 변수 a와 b를 가진 사용자 유형을 고려하십시오. 분명히 이것은 사용자가 두 가지 유형으로 구성 될 수있게합니다 :여러 유형 클래스가있는 사용자 정의 데이터 유형에 펑터/응용 프로그램 사용?

data Users a b = User a b deriving (Show, Eq, Ord) 

이 인스턴스에 대해 펑터와 응용 프로그램을 어떻게 선언 할 수 있습니까?

나는이 방법이 컴파일되지 않습니다 시도했다 :

instance Functor Users where 
    fmap f(User a b) = User (f a) (f b) 

instance Applicative Users where 
    pure a b = User a b 
    (<*>) User a b = (fmap a) (fmap b) 

이 컴파일되지 않습니다 이유는 무엇입니까?

+1

이 펑터 인스턴스가 종류가 있어야합니다 종류가 일치하지가'* -> *'당신'User' 유형이 종류의 반면'* -> 예상 할 수있는 바와 같이, (,)에 대한 인스턴스입니다 * -> *'. 원하는 것은 [Profunctor] (http://hackage.haskell.org/package/profunctors-5.2/docs/Data-Profunctor.html#t:Profunctor)입니다. – baxbaxwalanuksiwe

+3

종류 오류뿐 아니라 정의에 변수 'b'가 없기 때문에 '순수한'구현이 작동하지 않습니다. 'a -> User a b '함수를 어떻게 작성할 수있을 것으로 기대하십니까? – Lee

+2

@baxbaxwalanuksiwe 'Bifunctor'를 의미합니까? – ThreeFx

답변

5

두 인수에서 모두 재미있는 ADT 유형 클래스에 대해 Data.Bifunctor을보십시오. User은 튜플의 멋진 이름이며, 이미 이러한 인스턴스를 지원합니다. bifunctor 인스턴스를 파생하는 것은 Haskell에서 가능합니다.

@ 바쿠 리우는 Usernewtype으로 정의하고 내선 번호는 GeneralizedNewtypeDeriving으로 제안합니다.

두 번째로는 Biapplicative을 참조하십시오.

instance Biapplicative (,) where 
    pure = (,) 
    ap (f, g) (a, b) = (f a, g b) 
+1

'User'에'newtype'을 사용하여 쌍의 인스턴스를 파생시키고'GeneralizedNewtypeDeriving' 확장을 사용할 수 있습니다. – Bakuriu