2014-05-16 4 views
4

나는 다음과 같은 유형의 클래스와 인스턴스 한 사이 :중복 인스턴스를 두 번 적분 유형

class StatType a where 
    toDouble :: a -> Double 
instance StatType Double where 
    toDouble = id 
instance Integral a => StatType a where 
    toDouble = fromIntegral 

avg :: StatType a => [a] -> Double 
avg = undefined 

그러나 표현

*Example> avg ([1,2,3,4] :: [Double]) 

이 인스턴스에게

Overlapping instances for StatType Double 
    arising from a use of `avg' 
Matching instances: 
    instance StatType Double -- Defined at Example.hs:61:10 
    instance Integral a => StatType a -- Defined at Example.hs:63:10 
를 중복에 대한 유형의 오류를보고

유형 시스템에서이 두 인스턴스를 선택할 수 없습니다. 그러나 DoubleIntegral 유형이 아닙니다.

*Example> :i Double 
data Double = GHC.Types.D# GHC.Prim.Double# 
     -- Defined in `GHC.Types' 
instance StatType Double -- Defined at Example.hs: 
instance Enum Double -- Defined in `GHC.Float' 
instance Eq Double -- Defined in `GHC.Classes' 
instance Floating Double -- Defined in `GHC.Float' 
instance Fractional Double -- Defined in `GHC.Float' 
instance Num Double -- Defined in `GHC.Float' 
instance Ord Double -- Defined in `GHC.Classes' 
instance Read Double -- Defined in `GHC.Read' 
instance Real Double -- Defined in `GHC.Float' 
instance RealFloat Double -- Defined in `GHC.Float' 
instance RealFrac Double -- Defined in `GHC.Float' 
instance Show Double -- Defined in `GHC.Float' 

그리고 나는 Integral 중 하나가 암시한다고 생각하지 않습니까? DoubleIntegral 인스턴스가 아니기 때문에 fromIntegral (3 :: Double)은 형식 오류를 발생시킵니다.

왜 겹쳐 있습니까?

고마워요!

답변

7

은 아주 간단하게, 이것은 단지 얼마나 GHC works

GHC이 해결하려고 할 때, 말, 제약 C 지능 BOOL, 그것은 머리를 인스턴스화 에 의해 일치 제약에 대한 모든 인스턴스 선언에 시도

인스턴스 선언의 이 선언을 고려

instance context1 => C Int a  where ... -- (A) 
instance context2 => C a Bool where ... -- (B) 

GHC의 기본 동작은 정확히 하나 개의 인스턴스가이 해결하려고하는 제약 조건과 일치해야한다는 것입니다. 예를 들어 제약 C Int Bool은 인스턴스 (A)와 인스턴스 (B)를 일치 시키므로 거부됩니다. C Int Char은 (A)와 만 일치하므로 (A)가 선택됩니다.

  • 일치 GHC 인스턴스 선언의 문맥을 고려 더 없는지

    고지 (context1 등).

그래서 GHC는

instance StatType Double 
instance Integral a => StatType a 

볼 수 없습니다 그것은 분명 중복되는

instance StatType Double 
instance StatType a 

을 본다.

이것이 작동하는 이유는 유형 클래스가 열려 있기 때문입니다. Integral Double에 대한 인스턴스는 현재이지만 누군가가 라이브러리를 가져 와서 하나를 선언 할 수 있습니다. 인스턴스를 확인한 경우에도 인스턴스가 겹칠 수 있습니다. 더 나쁜 것은, 다른 하나를 선호하는 현명한 방법이 없을 것입니다.

+0

'OverlappingInstances'는 가장 구체적인 인스턴스를 선택하여이를 허용합니다.이것은 때로는 유용하지만,'instance Rational a => StatType a'라고 정의했다면, 즉시 다시 깨질 것입니다. – Dan

+2

OverlappingInstances를 사용하는 경우는 거의 없으며이 중 하나가 아닙니다. – user2407038

+0

이것은 완전히 의미가 있습니다. 감사. – Tim

관련 문제