diff --git a/CHANGELOG.md b/CHANGELOG.md index 2dfc2e0..7b98422 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,9 @@ 370](https://github.com/mrkkrp/megaparsec/issues/370). * Inlined `Applicative` operators `(<*)` and `(*>)`. [PR 566](https://github.com/mrkkrp/megaparsec/pull/566). +* `many` and `some` of the `Alternative` instance of `ParsecT` are now more + efficient, since they use the monadic implementations under the hood. + [Issue 567](https://github.com/mrkkrp/megaparsec/issues/567). ## Megaparsec 9.6.1 diff --git a/Text/Megaparsec.hs b/Text/Megaparsec.hs index bc7939d..d14da71 100644 --- a/Text/Megaparsec.hs +++ b/Text/Megaparsec.hs @@ -130,12 +130,16 @@ import Text.Megaparsec.Stream -- -- Note that we re-export monadic combinators from -- "Control.Monad.Combinators" because these are more efficient than --- 'Applicative'-based ones. Thus 'many' and 'some' may clash with the +-- 'Applicative'-based ones (†). Thus 'many' and 'some' may clash with the -- functions from "Control.Applicative". You need to hide the functions like -- this: -- -- > import Control.Applicative hiding (many, some) -- +-- † As of Megaparsec 9.7.0 'Control.Applicative.many' and +-- 'Control.Applicative.some' are as efficient as their monadic +-- counterparts. +-- -- Also note that you can import "Control.Monad.Combinators.NonEmpty" if you -- wish that combinators like 'some' return 'NonEmpty' lists. The module -- lives in the @parser-combinators@ package (you need at least version diff --git a/Text/Megaparsec/Internal.hs b/Text/Megaparsec/Internal.hs index 5eb065c..67900ad 100644 --- a/Text/Megaparsec/Internal.hs +++ b/Text/Megaparsec/Internal.hs @@ -46,6 +46,7 @@ where import Control.Applicative import Control.Monad +import qualified Control.Monad.Combinators import Control.Monad.Cont.Class import Control.Monad.Error.Class import qualified Control.Monad.Fail as Fail @@ -211,6 +212,8 @@ pAp m k = ParsecT $ \s cok cerr eok eerr -> instance (Ord e, Stream s) => Alternative (ParsecT e s m) where empty = mzero (<|>) = mplus + many = Control.Monad.Combinators.many + some = Control.Monad.Combinators.some -- | 'return' returns a parser that __succeeds__ without consuming input. instance (Stream s) => Monad (ParsecT e s m) where