4

나는 타입 레벨 프로그래밍에 대해 가르쳐 왔으며 간단한 자연수 덧셈 형 함수를 작성하려고했다. 다음과 같이 작동 나의 첫 번째 버전은 다음과 같습니다 데이터 킨으로 놀기 - 잘못된 매치 오류

data Z 
data S n 

type One = S Z 
type Two = S (S Z) 

type family Plus m n :: * 
type instance Plus Z n = n 
type instance Plus (S m) n = S (Plus m n) 

그래서 GHCi에서 내가 할 수있는 : 예상대로 작동

ghci> :t undefined :: Plus One Two 
undefined :: Plus One Two :: S * (S * (S * Z)) 

.

data Nat = Z | S Nat 

그리고 플러스 제품군은 이제 Nat 종류의 반환 :

type family Plus m n :: Nat 

문제가 있지만, 수정 된 코드는 컴파일 난 다음에 ZS 유형을 수정하여 DataKinds 확장을 시도하기로 결정 테스트 할 때 오류가 발생합니다.

Kind mis-match 
Expected kind `OpenKind', but `Plus One Two' has kind `Nat' 
In an expression type signature: Plus One Two 
In the expression: undefined :: Plus One Two 

Google에서 해결책을 찾았지만 실패했습니다. . 해결책이 존재합니까? 아니면 언어의 한계에 부딪 혔습니까?

+1

사용을 :kind!를 사용하여 Plus One Two의 종류를 얻을 수 ghci

ghci>:t (undefined :: 'Z) <interactive>:1:15: Kind mis-match Expected kind 'OpenKind', but 'Z' has kind 'Nat' In an expression type signature: Z In the expression: (undefined :: Z) 

이보십시오! 플러스 원 투 2 'ghci. – Satvik

+0

''undefined :: SomeType'에서'SomeType'은 친절한'*'이어야한다고 생각합니다. – Satvik

+0

런타임에 형식 감시를 ​​정말로 갖고 싶다면 표준 ['Proxy' 트릭] (http://hackage.haskell.org/packages/archive/tagged/0.4.4/doc/html/)을 사용할 수 있습니다. Data-Proxy.html). –

답변

7

테스트 방법이 올바르지 않다고 생각합니다. undefined은 종류가 * 인 모든 유형이 될 수 있습니다 (아마도 여기에 잘못되었습니다). 종류 :

당신은 여전히`ghci에

ghci>:kind! Plus One Two 
Plus One Two :: Nat 
= S (S (S 'Z)) 
+0

감사! 그거야. 물론 Nat는 *의 하위 (그게 뭐니?)일까요? –

+0

나는 하위 계열과 같은 것이 없다고 생각하지만 나는 전문가가 아니다. – Satvik

+0

@TomSavage : 아니요,'*'는 보이는 것보다 더 구체적입니다. [_lifted types_] (http://www.haskell.org/ghc/docs/7.4.2/html/users_guide/kind-polymorphism)입니다. - 및 - promotion.html). – leftaroundabout