我正在嘗試使用Parsec庫來解析Token
值的列表。我想使用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.Prim中的Stream
類定義具有Monad m => Stream [tok] m tok
作爲實例之一。 Stream [Token] Identity Token
是否已經被該實例覆蓋?其次,這是甚麼限制什麼?在mytoken
的類型中沒有類型變量可以被約束。
更糟糕的是,當我在另一個函數中使用新的「約束」mytoken
時,我得到的錯誤完全相同,它實際上需要在函數的類型上放置相同的,看似無操作類型的約束試圖撥打mytoken
。
如果任何人都可以幫我解釋一下這種類型約束是幹什麼的,我會非常感激。
太棒了!這工作。將來我會確保包含一個最低限度複製的文件。 在沒有導入適當的實例的情況下,您是否有任何洞察類型約束正在做什麼? – Cardano
@Cardano是的,當然。我會添加一個關於這個的句子。 –
請注意,最近這個實例已經[deorphanized](https://github.com/aslatter/parsec/commit/ec7d75098740d9315736f2464f09b699bf37f436),所以從下一個版本開始這不應該是個問題。 –