versions Generalized de oneOf
, noneOf
, et anyChar
peut être construit sur un satisfy
généralisé, assez facilement:
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
Il peut sembler que la généralisation de ces éléments semble manquante, mais vous remarquerez que ces généralisations supposent que le type t
peut ne pas être vrai pour le type de jeton de quelqu'un. Il est supposé être une instance de Show
et Eq
, mais je peux imaginer des types de jetons pour lesquels ils sont affichés d'une autre manière que show
, et que l'appartenance à une classe de jetons peut être obtenue via une autre méthode que ==
et elem
. Enfin, une fois que votre type de jeton n'est plus un Char
, la manière dont vous choisissez de représenter la position, et donc de la mettre à jour, dépend fortement de votre représentation des jetons et des flux. Par conséquent, je peux voir pourquoi une forme plus généralisée n'existe pas.
Les questions que vous avez nommés peuvent être résolus par: classe de types> Jeton de classe où un > showTok :: a -> Chaîne > nextPosTok :: (type approprié ici) > ... En fin de compte vous pouvez toujours 'newtype' votre type de jeton et fournir vos propres définitions. – Tener
@Tener - En effet, c'est comme cela que je le ferais - mais Parsec 3 n'a pas mis la fonction nextPos dans la classe de type Stream, ni défini une classe de type Token. – MtnViewMark