2014-04-04 6 views
4

Token 값 목록을 구문 분석하기 위해 Parsec 라이브러리를 사용하려고합니다. Text.Parsec.Prim에있는 token 함수를 사용하여 단일 값과 일치 시키려합니다. 이것은 컴파일 오류가 있습니다비 유형 변수 제한

type TokenParser a = Parsec [Token]() a 

mytoken :: (Token -> Bool) -> TokenParser Token 
mytoken test = token showTok posFromTok testTok 
    where -- and so on 

: : 그것은 작동합니다 같이 보인다

No instance for (Stream [Token] Identity Token) 
    arising from a use of `Prim.token' 
Possible fix: 
    add an instance declaration for (Stream [Token] Identity Token) 

좋아요를,의는 mytoken:

mytoken :: Stream [Token] Identity Token => (Token -> Bool) -> TokenParser Token 

이 우리 후 작동에 유형 선언을 변경할 수 있습니다 확장자는 {-# LANGUAGE FlexibleContexts #-}입니다.

무슨 일입니까? 먼저 Text.Parsec.PrimStream 클래스 정의에 인스턴스 중 하나로 Monad m => Stream [tok] m tok이 있습니다. 해당 인스턴스에 Stream [Token] Identity Token이 이미 적용되어야합니까? 둘째로, 이것은 심지어 어떤 것을 제약하는 것인가? mytoken 유형에는 제한 할 유형 변수가 없습니다.

또 다른 기능에서 새로운 "제한된"mytoken을 사용하려고하면 정확하게 동일한 오류가 발생합니다. 실제로는 함수의 유형에 동일하지 않은 겉보기에는 형식이없는 제약 조건이 필요합니다. mytoken에 전화하려고합니다.

누구든지이 유형의 제약이 무엇을하는지 설명 할 수 있다면 매우 감사하겠습니다.

답변

9

다음 파일은 문제를 재현 할 수있는 최소한의 파일입니다. (미래에, 당신은 우리와 같은 파일을 직접 작성해야합니다.)

import Text.Parsec.Prim 

data Token 

type TokenParser a = Parsec [Token]() a 

mytoken :: (Token -> Bool) -> TokenParser Token 
mytoken test = token showTok posFromTok testTok 

showTok = undefined 
posFromTok = undefined 
testTok = undefined 

Text.Parsec.PrimText.Parsec에 대한 수정 오류에서 가져 오기를 변경. (적절한 인스턴스는 Text.Parsec.Prim 수입되는, Text.Parsec.String에 정의되어 있습니다.) 또한이 변경이 작동 컴파일하지만 만드는 이유를 물어

mytoken :: Stream [Token] Identity Token => (Token -> Bool) -> TokenParser Token 

일반적인 규칙은 유형 "C => T가"라는 것을 : "당신은 제약 조건 C가 만족 스럽다는 것을 보여줄 수 있다면,이 것이 T 인 것처럼 사용할 수 있습니다." 따라서 mytoken의 유형을 mytoken까지 기다려야한다고 말하면 평범한 이전 (Token -> Bool) -> TokenParser Token처럼 사용하고 가능한 한 빨리 그 내용을 표시하는 의무를 이행하십시오. Stream [Token] Identity Token 당신은 여전히 ​​적절한 사례를 수입하지 않았으므로 그 의무를 이행 할 수 없으며 불평 할 수 없습니다.

+0

굉장! 그게 효과가 있었어. 앞으로 필자는 최소한으로 재생산하는 파일을 포함시킬 것입니다. 적절한 인스턴스를 가져 오지 못하는 경우 유형 제약 조건에 대한 통찰력을 갖고 있습니까? – Cardano

+1

@ Cardard 예, 물론입니다. 나는 이것에 대해 문장을 추가 할 것이다. –

+2

최근에이 인스턴스가 [deproanized] (https://github.com/aslatter/parsec/commit/ec7d75098740d9315736f2464f09b699bf37f436)되었으므로 다음 릴리스부터는 문제가되지 않습니다. –