Обобщенные версии oneOf
, noneOf
и anyChar
могут быть построены из обобщенного satisfy
, достаточно легко:
oneOfT :: (Eq t, Show t, Stream s m t) => [t] -> ParsecT s u m t
oneOfT ts = satisfyT (`elem` ts)
noneOfT :: (Eq t, Show t, Stream s m t) => [t] -> ParsecT s u m t
noneOfT ts = satisfyT (not . (`elem` ts))
anyT :: (Show t, Stream s m t) => ParsecT s u m t
anyT = satisfyT (const True)
satisfyT :: (Show t, Stream s m t) => (t -> Bool) -> ParsecT s u m t
satisfyT p = tokenPrim showTok nextPos testTok
where
showTok t = show t
testTok t = if p t then Just t else Nothing
nextPos p t s = -- however you update position for your token stream
Может показаться, что их обобщение отсутствует, но вы заметите, что в этих обобщениях сделаны некоторые предположения о типе t
, которые могут быть неверными для чей-то токена. Предполагается, что это пример Show
10 и Eq
, но я могу представить типы токенов, для которых они отображаются другим способом, чем show
, и что членство в классе токенов может быть достигнуто с помощью некоторого метода, отличного от ==
и elem
.
Наконец, как только ваш токен уже не является Char
, как вы выбираете представление позиции и, таким образом, обновляете его, сильно зависит от вашего представления токенов и потоков.
Следовательно, я вижу, почему более обобщенная форма не существует.
вопросы вы назвали может быть решена: класса типов > класс фишку где > showTok :: а -> Строка > nextPosTok :: (соответствующий тип здесь) > ... В конце концов вы всегда можете «newtype» использовать свой токен и предоставлять свои собственные определения. – Tener
@Tener - Действительно, так я бы это сделал, но Parsec 3 не помещал функцию nextPos в класс типа Stream, а также не определял тип маркера Token. – MtnViewMark