Я пытаюсь использовать библиотеку Parsec для анализа списка значений Token
. Я хочу использовать функцию token
в тексте .Parsec.Prim для соответствия одному значению. Кажется, это должно работать:
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 #-}
.
Что здесь происходит? Прежде всего, определение класса Stream
в Text. Parsec.Prim имеет Monad m => Stream [tok] m tok
в качестве одного из экземпляров. Разве Stream [Token] Identity Token
уже не должно быть охвачено этим экземпляром? Во-вторых, как получается, что это вообще что-то ограничивает? В типе mytoken
нет переменных типа, которые должны быть ограничены.
Что еще хуже, когда я собираюсь использовать свою новую «ограниченную» mytoken
в другой функции, я получаю точно такую же ошибку, No instance for (Stream [Token] Identity Token) arising from...
На самом деле это требует наложения того же, по-видимому, ограничения типа no-op для типа функции, пытающейся вызвать mytoken
.
Если кто-нибудь может помочь объяснить мне, что делает это ограничение типа, я был бы очень признателен.