Using MonadError with Parsec

I am trying to use MonadError with Parsec. I came up with the following code snippet:

f5 = do
    char 'a'
    throwError "SomeError"

f6 = f5 `catchError` (\e -> unexpected $ "Got the error: " ++ e)

ret = runErrorT (runParserT f6 () "stdin" "a")

However ret- Left "SomeError"it seems that catchError has no effect. What is the correct way to use MonadError here?

I would prefer to use MonadError for native Parsec error handling, for example, when I have:

try (many1 parser1) <|> parser2

If parser1 does not work here, parser2 will continue, but I would like to have an exception that completely cancels the parsing.

+3
source share
3 answers

I get the impression that you are trying to attract MonadErrorfor the wrong reason.

try (many1 parser1) <|> parser2 , , try <|> - , . , , (many1 parser1) >> parser2, ? ( (many1 parser1), >>= (many1 parser1) parser2.)


(: , , , , ... , () , t .)

ParsecT/MonadError. , , , , OP , , , , .

-, , , Parsec MonadError. - , , - ; ParsecT MonadError , , MonadError . GHCi:

> :i Parsec
type Parsec s u = ParsecT s u Identity
    -- Defined in Text.Parsec.Prim
-- no MonadError instance

instance (MonadError e m) => MonadError e (ParsecT s u m)
  -- Defined in Text.Parsec.Prim
-- this explains why the above is the case
-- (a ParsecT-created monad will only become an instance of MonadError through
-- this instance, unless of course the user provides a custom declaration)

, catchError ParsecT. GHCi:

> (runParserT (char 'a' >> throwError "some error") () "asdf" "a" :: Either String (Either ParseError Char)) `catchError` (\e -> Right . Right $ 'z')
Right (Right 'z')

(, , , , ). GHC :

Either String (Either ParseError Char)

, - Either ParseError Char - Either String Identity. Either String MonadError, throwError/catchError, , catchError, , , . , .

. . ret, :

forall (m :: * -> *) a.
(Monad m) =>
m (Either [Char] (Either ParseError a))

( GHCi... , {-# LANGUAGE NoMonomorphismRestriction #-}, .)

- - ret. :

> runParserT ret () "asdf" "a"
Right (Left "some error")

, , catchError, unexpected, , , ( ) ... , , - .

+4

, , error, Debug.Trace -.

, , - try (...) <|>, , , .

, , , - ( ), .

, , , , , ... - , Parsec, . , Haskell .

: Parsec MonadError, - , . , , Parsec, , , , , "". , Parsec ( ) .

, Parsec, , , .

+2

, - try (...) < | > , , , .

, , , - ( ), .

, . , , . , . , . . . , , , "" "" . , , .

+2

Source: https://habr.com/ru/post/1731055/


All Articles