2013-01-01 1 views
4

형식 서명의 시작 부분에 forall을 명시 적으로 추가하지 않으면 함수가 형식 확인에 실패하는 상황이 발생했습니다. 당해명시 적 forall을 생략하면 모호한 형식 오류가 발생합니다.

함수이다

test :: (Typeable a) => a -> a 
test x 
    | typeOf (undefined :: a) == typeOf (undefined :: a) = x 
    | otherwise = x 

GHC 위의 다음의 경고를 제공한다 :

Ambiguous type variable `a0' in the constraint: 
    (Typeable a0) arising from a use of `typeOf' 
Probable fix: add a type signature that fixes these type variable(s) 
In the first argument of `(==)', namely `typeOf (undefined :: a)' 
In the expression: 
    typeOf (undefined :: a) == typeOf (undefined :: a) 
In a stmt of a pattern guard for 
       an equation for `test': 
    typeOf (undefined :: a) == typeOf (undefined :: a) 

Ambiguous type variable `a1' in the constraint: 
    (Typeable a1) arising from a use of `typeOf' 
Probable fix: add a type signature that fixes these type variable(s) 
In the second argument of `(==)', namely `typeOf (undefined :: a)' 
In the expression: 
    typeOf (undefined :: a) == typeOf (undefined :: a) 
In a stmt of a pattern guard for 
       an equation for `test': 
    typeOf (undefined :: a) == typeOf (undefined :: a) 

는 따라서 정의되지 않은 값의 두 가지 유형을 통합 못하고있다. 그러나 앞에 a를 추가하면 :

test :: forall a. (Typeable a) => a -> a 
test x 
    | typeOf (undefined :: a) == typeOf (undefined :: a) = x 
    | otherwise = x 

잘 컴파일됩니다. 이

{-# LANGUAGE GADTs, StandaloneDeriving, DeriveDataTypeable, 
ScopedTypeVariables, FlexibleInstances, UndecidableInstances, 
Rank2Types #-} 

를 사용 GHC 7.4.2에 나는 GHC의 문서에서 제시 한 바와 같은 형태의 서명에 "FORALL"생략 (암시 적으로 관련된 모든 형태 변수를 통해 처음으로 foralls를 추가 할 해당하는 것을 인상이었다 : http://www.haskell.org/ghc/docs/7.4.2/html/users_guide/other-type-extensions.html). 왜 첫 번째 코드 조각은 유형 검사가 아닌 반면 두 번째 코드 조각은 무엇입니까?

답변

7

ScopedTypeVariables 확장자는 의미 값을 최상위 레벨 forall 수량 한정자에 추가합니다. 이는 바인딩 본문에 대한 유형 변수에 대한 범위 지정을 제공합니다. 그 forall없이

은 라인 3 a 변수 형태는 그들과 a0a1 라벨링하여 라인 오류 메시지가 이것을 나타내는 1에 a 상이한 유형 가변적이다. 그것들이 같은 타입이 아니라면 3 행의 타입은 모호하다. 왜냐하면 그것이 완전히 제약을받지 않기 때문이다.

+1

ref : http://www.haskell.org/ghc/docs/latest/html/users_guide/other-type-extensions.html#decl-type-sigs –

+0

두 분 모두 감사합니다. ScopedTypeVariables 덕분에 클래스 선언 내부에서 비슷한 구조를 사용하고 있었기 때문에 혼란 스러웠습니다. 이 문서는 클래스 선언이'forall'처럼 유형 변수를 범위에 가져 오기 때문에 이것이 사실이라고 설명합니다. –

관련 문제