廣義的版本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
和Eq
的一個實例,但我可以想象它們以其他方式顯示的令牌類型,而不是show
,並且可以通過==
和elem
以外的某種方法實現一類令牌中的成員資格。
最後,一旦您的令牌類型不再是Char
,您選擇表示位置並進行更新的方式高度依賴於您對令牌和流的表示。
因此,我可以看到爲什麼更廣義的形式不存在。
你命名可以通過類型類來解決這些問題: >類令牌,其中 > showTok :: A - >字符串 > nextPosTok ::(適當的類型這裏) > ... 到底你總是可以''newtype'你的令牌類型並提供你自己的定義。 – Tener 2010-03-19 16:55:39
@Tener - 事實上,我就是這麼做的 - 但Parsec 3沒有在Stream類中放入nextPos函數,也沒有定義Token類型類。 – MtnViewMark 2010-03-19 22:55:46