Использование parseTest в мегапарсек 7.0.4 - PullRequest
0 голосов
/ 01 декабря 2018

Появление кода означает, что я впервые использую мегапарсек.И с прошлого раза все изменилось.Предполагая, что

import qualified Text.Megaparsec as MP
import qualified Text.Megaparsec.Char as C

Я пытался

MP.parseTest (C.char '+') "+"

в GHCI, что дает следующее довольно бесполезное сообщение об ошибке:

interactive>:121:1: error:
* Ambiguous type variable `e0' arising from a use of `MP.parseTest'
  prevents the constraint `(MP.ShowErrorComponent
                              e0)' from being solved.
  Probable fix: use a type annotation to specify what `e0' should be.
  These potential instance exist:
    one instance involving out-of-scope types
    (use -fprint-potential-instances to see them all)
* In the expression: MP.parseTest (C.char '+') "+"
  In an equation for `it': it = MP.parseTest (C.char '+') "+"

<interactive>:121:15: error:
* Ambiguous type variable `e0' arising from a use of `C.char'
  prevents the constraint `(Ord e0)' from being solved.
  Probable fix: use a type annotation to specify what `e0' should be.
  These potential instances exist:
    instance (Ord a, Ord b) => Ord (Either a b)
      -- Defined in `Data.Either'
    instance Ord Ordering -- Defined in `ghc-prim-0.5.3:GHC.Classes'
    instance Ord Integer
      -- Defined in `integer-gmp-1.0.2.0:GHC.Integer.Type'
    ...plus 25 others
    ...plus 131 instances involving out-of-scope types
    (use -fprint-potential-instances to see them all)
* In the first argument of `MP.parseTest', namely `(C.char '+')'
  In the expression: MP.parseTest (C.char '+') "+"
  In an equation for `it': it = MP.parseTest (C.char '+') "+"

Правильно ли я использую это?Что мне нужно сделать, чтобы это исправить?

1 Ответ

0 голосов
/ 01 декабря 2018

Последние версии «мегапарсек» поддерживают пользовательские типы ошибок , определенные пользователем.Тип ParsecT параметризован типом пользовательских ошибок.Для поддержки симпатичной печати (как в parseTest) такие пользовательские ошибки должны быть экземплярами классов типов Ord и ShowErrorComponent.

Если мы никогдавыбрасывайте любые пользовательские ошибки, тип ошибки остается полиморфным.Но в конце, при печати результатов, мы должны предоставить конкретный тип.Мы можем использовать необитаемый тип Void из пакета "void" и информировать средство проверки типов, используя явную сигнатуру типа.

Документация рекомендует определение синонима типа, например type Parser = Parsec Void Text и использовать его в своих подписях.

Другой способ избежать двусмысленности - использовать приложение видимого типа :

Prelude Text.Megaparsec Data.Void> :t parseTest
parseTest
  :: (ShowErrorComponent e, Show a, Stream s) =>
     Parsec e s a -> s -> IO ()
Prelude Text.Megaparsec Data.Void> :set -XTypeApplications
Prelude Text.Megaparsec Data.Void> :t parseTest @Void
parseTest @Void
  :: (Show a, Stream s) => Parsec Void s a -> s -> IO ()
...