我正在尝试在haskell中构建一个错误报告解析器。目前我一直在寻找一个教程,这是我到目前为止所做的。
type Position = (Int, Int)
type Err = (String, Position)
newtype Parser1 a = Parser1 {parse1 :: StateT String (StateT Position (MaybeT
(Either Err))) a} deriving (Monad, MonadState String, Applicative, Functor)
runParser :: Parser1 a -> String -> Either Err (Maybe ((a, String), Position))
runParser p ts = runMaybeT $ runStateT (runStateT (parse1 p) ts) (0, 0)
basicItem = Parser1 $ do
state <- get
case state of
(x:xs) -> do {put xs; return x}
[] -> empty
item = Parser1 $ do
c <- basicItem
pos <- lift get
lift (put (f pos))
return c
f :: Char -> Position -> Position
f d (ln, c) = (ln + 1, 0)
f _ (ln, c) = (ln , c + 1)
这段代码不能编译,我认为这与我的项解析器以及我试图访问内部状态即位置的事实有关。我想知道如何在derinding子句中使Haskell在我的解析器类型中派生出两个状态的实例,那么我可以访问内部状态吗?
编辑1:
我最初尝试将basicItem声明为:
basicItem :: (MonadState String m, Alternative m) => m t
basicItem = do
state <- get
case state of
(x:xs) -> do {put xs; return x}
[] -> empty`
我想知道为什么它不能从MonadState String m中推断出get的上下文, 在我的派生条款中,我有MonadState字符串。