2011-06-25 53 views
16

我正在使用Parsec解析表達式,並且想要使用Parsec中的用戶狀態跟蹤這些表達式中的變量。不幸的是,我真的不知道該怎麼做。Parsec中的用戶狀態

考慮下面的代碼:

import Data.Set as Set 
inp = "$x = $y + $z" 

data Var = V String 

var = do char '$' 
     n <- many1 letter 
     let v = Var n 
     -- I want to modify the set of variables here 
     return v 

parseAssignment = ... -- parses the above assignment 

run = case runIdentity $ runParserT parseAssignment Set.empty "" inp of 
        Left err -> ... 
        Right -> ... 

所以,在ParsecT s u m auSet.Set。但是,我將如何將狀態更新集成到var

我試過類似modify $ Set.insert v,但這不起作用,因爲Set.Set不是狀態單子。

回答

16

不幸的是,updateParserState Yuras的建議,是不是最佳的(你會使用如果你正在尋找修改秒差距的內部狀態以及該功能);相反,你應該通過的作品在您的自定義用戶狀態的功能(即類型u -> u),以modifyState,如下面的例子:

expr = do 
    x <- identifier 
    modifyState (+1) 
    --^in this example, our type u is Int 
    return (Id x) 

,或者使用的getStateputState功能的任意組合。對於你的情況,你會做這樣的事情:

modifyState (Set.insert v) 

更多信息,請參見this link

欲瞭解更多類似於使用Parsec中的用戶狀態的教程介紹,this document雖然很老,但應該是相關的。

+0

謝謝!這正是我需要的 - 可能更早看過那個函數......我不知何故認爲modifyState與從Control.Monad.State中修改相關。 – bzn

+0

@bzn:雖然是相關的!如果你認爲Parsec是一個只保存用戶狀態的狀態monad,他們也會做同樣的事情。它們的區別僅在於「modifyState」忽略了Parsec的內部狀態。 –

1

您可以使用updateParserState

+0

謝謝,這有效,但正如Raeez Lorgat所說,modifyState似乎是我需要的功能。 – bzn