2015-01-31 5 views
4

방금 ​​유형을 배우기 시작했습니다. GHC 문서에는 최상위 레벨 및 관련 유형 패밀리가 동일한 기능을 가지고 있지만 작성중인 코드는 패밀리가 연결될 때와 다른 방식으로 최상위 레벨에서 작동합니다. 이는 컴파일과 잘 실행 :유형 가족 : 최상위 수준 vs. 연결된

{-# LANGUAGE TypeFamilies #-} 
module Test where 

-- type family R a 
-- type instance R Maybe = Int 

class C' a where 
    type R a 
    getInt' :: a Int 
    getBool' :: R a -> a Bool 

instance C' Maybe where 
    type R Maybe = Int 
    getInt' = Just 3 
    getBool' i = Just $ i < 10 

printer :: IO() 
printer = print $ (getBool' 5 :: Maybe Bool) 

을하지만이 나에게 타입 에러 제공 :

{-# LANGUAGE TypeFamilies #-} 
module Test where 

type family R a 
type instance R Maybe = Int 

class C' a where 
    -- type R a 
    getInt' :: a Int 
    getBool' :: R a -> a Bool 

instance C' Maybe where 
    -- type R Maybe = Int 
    getInt' = Just 3 
    getBool' i = Just $ i < 10 

printer :: IO() 
printer = print $ (getBool' 5 :: Maybe Bool) 

이 나에게 동일한 모양을; 왜 컴파일되고 다른 컴파일은되지 않습니까? 나는 오른쪽 종류에만 관련된 유형의 가족을 위해 추정되는 어떤 이유가 있다고 생각하지 않습니다

type family R (a :: * -> *) 

: 당신이 종류의 주석을 경우

+0

관련 유형 패밀리는 컴파일러가 모든 클래스 인스턴스에서 하나 이상의 유형 인스턴스를 필요로한다는 점에서 만 다릅니다. 문서에서 "같은 기능"이라고 말하면 동일한 선언에 대해 의미가 동일 함을 의미하지만 올바른 위치에 선언을 배치해야합니다. 타입 패밀리를 "연관시키는"목적은 구현 자에게 그 타입 인스턴스를 정의해야 함을 상기시키는 것이다. – user2407038

답변

5

두 번째는 작동합니다.

+3

유형 패밀리를 사용하는 함수에 추가 유형 정보가 있고 클래스 선언에서 유형이 'a'이므로 관련 유형 패밀리에 대해 올바른 종류가 유추됩니다. 예를 들어''Int''는'* :: *'와 같이 유추 할 수있는 유효한 타입의 종류 여야합니다. 타입 패밀리가 연관되어 있지 않으면, 컴파일러는 분명히 그 정보에 접근 할 수 없기 때문에 타입 패밀리에 디폴트 타입 인'* -> *'를 준다. – user2407038

+0

나는 컴파일러가 분명히 그 정보에 접근 할 수 없다는 것에 동의하지 않는다. 그것은 그 파일에서 사용할 수있는 것 같습니다, 그것은 아무 이유없이 사용되지 않습니다 (아무도 그것을 요구하지 않았습니다, 그것은 구현하기가 너무 어렵습니다. 종류를 결정할 때 너무 혼란 스럽습니다). – aavogt

+0

동의합니다 어떤 의미에서든 불가능 *하지 않습니다. 나는 라인을 따라 더 많은 것을 의미했다. 컴파일러는 타입 패밀리의 타입을 결정하기 위해 사이트를 사용하지 않는다. 아마 솔루션을 그렇게 간단하기 때문에 특히 그렇게하는 것이 타당하지 않을 것입니다. – user2407038

관련 문제