2009-11-29 6 views
13

하스켈에서 클래스 인스턴스를 쉽게 "들어 올리는"방법이 있습니까?하스켈에서 클래스 인스턴스 해제하기

내가 자주 예를 들어, 만들 필요 봤는데, 이런 종류의 생성자를 통해 그냥 "리프팅"인분 구조 몇 가지 클래스에 대한 민 인스턴스 :

data SomeType a = SomeCons a 

instance (Num a)=>Num SomeCons a where 
    (SomeCons x) + (SomeCons y) = SomeCons (x+y) 
    negate (SomeCons x) = SomeCons (negate x) 
    -- similarly for other functions. 

이를 방지 할 수있는 방법이 있나요 보일러 플레이트 및이 Num 구조를 자동으로 "들어 올립니다"? 나는 보통 Show와 다른 클래스들과 함께 이것을해야만한다. 왜냐하면 내가 existencials를 배우려고 할 때 컴파일러는 deriving(Show)을 사용하지 않을 것이다.

답변

19

일반화 된 newtype은 파생 확장은 여기에 원하는 것입니다 :

{-# LANGUAGE GeneralizedNewtypeDeriving #-} 

module Main where 

newtype SomeType a = SomeCons a deriving (Num, Show, Eq) 

main = do 
    let a = SomeCons 2 
     b = SomeCons 3 
    print $ a + b 

출력 :

*Main> main 
SomeCons 5 
+1

흠 ...이 newtype은 함께하지만 데이터와 함께 작동 왜? –

+3

newtype은 생성자 또는 필드를 추가 할 수 없으므로 기존 유형을 다시 래핑합니다. 이렇게하면 Extension이 일반적으로 모든 데이터 유형에 대해 파생 할 수있는 클래스 대신 모든 클래스에서 작동 할 수 있습니다. – Martijn

5

GHC는 사용자가 원하는 것을 구현합니다 : Extensions to the deriving mecanism. 이러한 수정은 종종, (haskell' wiki에서 볼 수 있듯이) 미래의 표준 언어 확장

, 당신은 다음과 프라그를

{-# GeneralizedNewtypeDeriving #-} 

를 사용해야합니다이 확장을 활성화하고 다음 newtype이란 선언에 유도를 사용하기 위해 표시됩니다 보통

data SomeType a = SomeCons a deriving (Num) 
1

GeneralizedNewtypeDeriving