2017-04-14 20 views
5

가정하자 나는 어떤 종류의 [*], 유형의 목록이 있습니다 그래서 지금까지다형성 함수는

type family Tupled (ts :: [*]) z :: * 
type instance Tupled (t ': ts) z = (t, Tupled ts z) 
type instance Tupled '[] z = z 

:

let Ts = '[Int, Bool, Char] 

내가 튜플의 체인이를 변환 할 좋은 :

> :kind! Tupled Ts() 
Tupled Ts() :: * 
= (Int, (Bool, (Char,()))) 

는 지금은 기능을 표현하는 유형 Fun을 쓸 수 있도록하고 싶습니다 그 이 사슬의 "바닥"에 다형성이있다.

(Int, (Bool, (Char, (String,())))) 
(Int, (Bool, (Char, (Word, (ByteString,()))))) 

내가이 시도 : 예를 들어, Fun Ts Ts는 이러한 유형 중 하나에 작업을해야

newtype Fun as bs = Fun 
    { unfun :: forall z. Tupled as z -> Tupled bs z } 

를하지만 유형 체킹 실패 : 내가 사용하는 권장 사항을 본 적이

Couldn't match type ‘Tupled bs z’ with ‘Tupled bs z0’ 
NB: ‘Tupled’ is a type function, and may not be injective 
The type variable ‘z0’ is ambiguous 
Expected type: Tupled as z -> Tupled bs z 
    Actual type: Tupled as z0 -> Tupled bs z0 
In the ambiguity check for the type of the constructor ‘Fun’: 
    Fun :: forall z. Tupled as z -> Tupled bs z 
To defer the ambiguity check to use sites, enable AllowAmbiguousTypes 
In the definition of data constructor ‘Fun’ 
In the newtype declaration for ‘Fun’ 

분사 성 문제를 피하는 데이터 패밀리 :

data family Tupled (ts :: [*]) z :: * 
data instance Tupled (t ': ts) z = Cons t (Tupled ts z) 
data instance Tupled '[] z = Nil 
Fun $ \ (i, (b, (c, z))) -> (succ i, (not b, (pred c, z))) 

내가 해결할 수 있습니다

: Fun 컴파일하게,하지만이 같은 튜플 작업을 찾고 있어요 때 ConsNil의 땅에서 그 날을 얻는다 같이 "붙어"보이는

그리고 실제로 어떻게 든이?

+0

왜 'type fun as bs = forall z? z로 연결됨 -> 합쳐서 bs z'? –

+0

@ Li-yaoXia : 'Fun'을 'Fun'에 인수로 전달할 수 있기를 원하기 때문에 impredicativity를 숨기려면 'newtype'이 필요합니다. –

답변

4

AllowAmbiguousTypes을 사용하십시오. GHC 8에서 모호성 검사는 완전히 불필요합니다. 왜냐하면 어떤 (근본적으로 해결 가능한) 모호성이 유형 응용 프로그램으로 해결 될 수 있기 때문입니다. 또한 유형 응용 프로그램 없이도 Fun을 명확하게 사용할 수 있으므로 모호성 검사에 대한 귀하의 사례는 오 탐지에 불과합니다.

+0

이 질문에 유의해야하지만이 기능을 사용하면 아무런 차이가없는 것처럼 보입니다. 동일한 오류 메시지가 나타납니다. 저는'lts-8.9' Stack resolver에서 GHC 8.0.2를 사용하고 있습니다. –

+0

이 [file] (http://lpaste.net/354579)은 GHC 8.0.1과 8.0.2에서 모두 허용됩니다. 나는 당신의 편에서 무엇이 잘못되었는지를 확신하지 못한다. (또한 나는 닫힌 타입의 familiy를 사용했다. –

+1

아하,'newtype Fun as bs = 재미 (forall z. ...)'typechecks,하지만'... = Fun {unfun :: forall z. ...}'하지 않습니다. 나는 'unfun'의 정의 *가 모호한 * 사용 사이트 *로 간주되기 때문에 혼란 스러웠습니다. 그것을 별도의 함수로 만들고'unfun :: forall bs z 형식 응용 프로그램을 사용하십시오. fun as bs -> tupleed z -> Tupled bs z; unfun (Fun f) as = fz는 문제를 해결합니다. 이 점을 이해하도록 도와 주셔서 감사합니다. :) –