packages feed

distributors 0.4.0.0 → 0.5.0.0

raw patch · 20 files changed

+811/−564 lines, 20 filesdep +megaparsecPVP ok

version bump matches the API change (PVP)

Dependencies added: megaparsec

API changes (from Hackage documentation)

- Control.Lens.Internal.NestedPrismTH: instance GHC.Classes.Eq Control.Lens.Internal.NestedPrismTH.NCon
- Control.Lens.Internal.NestedPrismTH: instance Language.Haskell.TH.Lens.HasTypeVars Control.Lens.Internal.NestedPrismTH.NCon
- Control.Lens.Internal.NestedPrismTH: makeNestedPrisms :: Name -> DecsQ
- Control.Lens.PartialIso: instance (Data.Profunctor.Unsafe.Profunctor p, GHC.Base.Functor (p a), Witherable.Filterable f) => Witherable.Filterable (Control.Lens.Internal.Profunctor.WrappedPafb f p a)
- Control.Lens.PartialIso: instance (Data.Profunctor.Unsafe.Profunctor p, GHC.Base.Functor f) => GHC.Base.Functor (Control.Lens.Internal.Profunctor.WrappedPafb f p a)
- Control.Lens.PartialIso: instance (Data.Profunctor.Unsafe.Profunctor p, Witherable.Filterable (p a)) => Witherable.Filterable (Data.Profunctor.Yoneda.Coyoneda p a)
- Control.Lens.PartialIso: instance (Data.Profunctor.Unsafe.Profunctor p, Witherable.Filterable (p a)) => Witherable.Filterable (Data.Profunctor.Yoneda.Yoneda p a)
- Control.Lens.PartialIso: instance (Data.Profunctor.Unsafe.Profunctor p, Witherable.Filterable f) => Data.Profunctor.Choice.Cochoice (Control.Lens.Internal.Profunctor.WrappedPafb f p)
- Control.Lens.PartialIso: instance Witherable.Filterable (Data.Profunctor.Types.Forget r a)
- Control.Lens.PartialIso: instance Witherable.Filterable f => Witherable.Filterable (Data.Profunctor.Types.Star f a)
- Data.Profunctor.Grammar: instance (GHC.Base.Alternative m, GHC.Base.Monad m) => Control.Monad.Fail.Try.MonadTry (Data.Profunctor.Grammar.Parsor s m a)
- Data.Profunctor.Grammar: instance (GHC.Base.Alternative m, GHC.Base.Monad m) => Control.Monad.Fail.Try.MonadTry (Data.Profunctor.Grammar.Printor s m a)
- Data.Profunctor.Grammar.Parsector: ParsecError :: TokenClass (Item s) -> [Tree String] -> ParsecError s
- Data.Profunctor.Grammar.Parsector: [parsecError] :: ParsecState s a -> ParsecError s
- Data.Profunctor.Grammar.Parsector: data ParsecError s
- Data.Profunctor.Grammar.Parsector: instance (Control.Lens.Grammar.Token.Categorized (GHC.IsList.Item s), GHC.Read.Read (GHC.IsList.Item s), GHC.Read.Read (Control.Lens.Grammar.Token.Categorize (GHC.IsList.Item s))) => GHC.Read.Read (Data.Profunctor.Grammar.Parsector.ParsecError s)
- Data.Profunctor.Grammar.Parsector: instance (Control.Lens.Grammar.Token.Categorized (GHC.IsList.Item s), GHC.Show.Show (GHC.IsList.Item s), GHC.Show.Show (Control.Lens.Grammar.Token.Categorize (GHC.IsList.Item s))) => GHC.Show.Show (Data.Profunctor.Grammar.Parsector.ParsecError s)
- Data.Profunctor.Grammar.Parsector: instance Control.Lens.Grammar.Token.Categorized (GHC.IsList.Item s) => GHC.Base.Monoid (Data.Profunctor.Grammar.Parsector.ParsecError s)
- Data.Profunctor.Grammar.Parsector: instance Control.Lens.Grammar.Token.Categorized (GHC.IsList.Item s) => GHC.Base.Semigroup (Data.Profunctor.Grammar.Parsector.ParsecError s)
- Data.Profunctor.Grammar.Parsector: instance Control.Lens.Grammar.Token.Categorized (GHC.IsList.Item s) => GHC.Classes.Eq (Data.Profunctor.Grammar.Parsector.ParsecError s)
- Data.Profunctor.Grammar.Parsector: instance Control.Lens.Grammar.Token.Categorized (GHC.IsList.Item s) => GHC.Classes.Ord (Data.Profunctor.Grammar.Parsector.ParsecError s)
- Data.Profunctor.Monoidal: instance (Data.Profunctor.Closed.Closed p, Data.Distributive.Distributive f) => Data.Profunctor.Closed.Closed (Control.Lens.Internal.Profunctor.WrappedPafb f p)
- Data.Profunctor.Monoidal: instance (Data.Profunctor.Monoidal.Monoidal p, Data.Profunctor.Monoidal.Monoidal q) => GHC.Base.Applicative (Data.Bifunctor.Product.Product p q a)
- Data.Profunctor.Monoidal: instance (Data.Profunctor.Monoidal.Monoidal p, GHC.Base.Applicative (q a)) => GHC.Base.Applicative (Data.Profunctor.Composition.Procompose p q a)
- Data.Profunctor.Monoidal: instance (Data.Profunctor.Unsafe.Profunctor p, GHC.Base.Alternative (p a)) => GHC.Base.Alternative (Data.Profunctor.Yoneda.Coyoneda p a)
- Data.Profunctor.Monoidal: instance (Data.Profunctor.Unsafe.Profunctor p, GHC.Base.Alternative (p a)) => GHC.Base.Alternative (Data.Profunctor.Yoneda.Yoneda p a)
- Data.Profunctor.Monoidal: instance (Data.Profunctor.Unsafe.Profunctor p, GHC.Base.Alternative (p a), GHC.Base.Applicative f) => GHC.Base.Alternative (Control.Lens.Internal.Profunctor.WrappedPafb f p a)
- Data.Profunctor.Monoidal: instance (Data.Profunctor.Unsafe.Profunctor p, GHC.Base.Applicative (p a)) => GHC.Base.Applicative (Data.Profunctor.Yoneda.Coyoneda p a)
- Data.Profunctor.Monoidal: instance (Data.Profunctor.Unsafe.Profunctor p, GHC.Base.Applicative (p a)) => GHC.Base.Applicative (Data.Profunctor.Yoneda.Yoneda p a)
- Data.Profunctor.Monoidal: instance (Data.Profunctor.Unsafe.Profunctor p, GHC.Base.Applicative (p a), GHC.Base.Applicative f) => GHC.Base.Applicative (Control.Lens.Internal.Profunctor.WrappedPafb f p a)
- Data.Profunctor.Monoidal: instance (GHC.Base.Applicative f, GHC.Base.Applicative (p a)) => GHC.Base.Applicative (Data.Profunctor.Cayley.Cayley f p a)
- Data.Profunctor.Monoidal: instance (GHC.Base.Functor f, GHC.Base.Functor (p a)) => GHC.Base.Functor (Data.Profunctor.Cayley.Cayley f p a)
- Data.Profunctor.Monoidal: instance Control.Arrow.Arrow p => Data.Profunctor.Unsafe.Profunctor (Control.Applicative.WrappedArrow p)
- Data.Profunctor.Monoidal: instance Control.Arrow.Arrow p => GHC.Base.Applicative (Data.Profunctor.Types.WrappedArrow p a)
- Data.Profunctor.Monoidal: instance Control.Arrow.Arrow p => GHC.Base.Functor (Data.Profunctor.Types.WrappedArrow p a)
- Data.Profunctor.Monoidal: instance Data.Functor.Contravariant.Divisible.Decidable f => GHC.Base.Applicative (Data.Bifunctor.Clown.Clown f a)
- Data.Profunctor.Monoidal: instance GHC.Base.Applicative (Control.Lens.Internal.Prism.Market a b s)
- Data.Profunctor.Monoidal: instance GHC.Base.Applicative f => GHC.Base.Applicative (Data.Bifunctor.Joker.Joker f a)
- Data.Profunctor.Monoidal: instance GHC.Base.Monoid r => GHC.Base.Applicative (Data.Profunctor.Types.Forget r a)
+ Control.Lens.Grammar: applicativeG :: (Alternative f, TokenAlgebra token (f token), TerminalSymbol token (f ()), forall x. BackusNaurForm (f x)) => Grammar token a -> f a
+ Control.Lens.Grammar: monadG :: (MonadTry m, TokenAlgebra token (m token), TerminalSymbol token (m ())) => CtxGrammar token a -> m a
+ Control.Lens.Grammar: readG :: CtxGrammar Char a -> ReadP a
+ Control.Lens.Grammar.BackusNaur: instance (forall x. Control.Lens.Grammar.BackusNaur.BackusNaurForm (f x)) => Control.Lens.Grammar.BackusNaur.BackusNaurForm (Data.Bifunctor.Joker.Joker f a b)
+ Control.Lens.Grammar.BackusNaur: instance Control.Lens.Grammar.BackusNaur.BackusNaurForm (Text.ParserCombinators.ReadP.ReadP a)
+ Control.Lens.Grammar.Internal.NestedPrismTH: instance GHC.Classes.Eq Control.Lens.Grammar.Internal.NestedPrismTH.NCon
+ Control.Lens.Grammar.Internal.NestedPrismTH: instance Language.Haskell.TH.Lens.HasTypeVars Control.Lens.Grammar.Internal.NestedPrismTH.NCon
+ Control.Lens.Grammar.Internal.NestedPrismTH: makeNestedPrisms :: Name -> DecsQ
+ Control.Lens.Grammar.Internal.Orphanage: instance (Data.Profunctor.Closed.Closed p, Data.Distributive.Distributive f) => Data.Profunctor.Closed.Closed (Control.Lens.Internal.Profunctor.WrappedPafb f p)
+ Control.Lens.Grammar.Internal.Orphanage: instance (Data.Profunctor.Unsafe.Profunctor p, GHC.Base.Alternative (p a)) => GHC.Base.Alternative (Data.Profunctor.Yoneda.Coyoneda p a)
+ Control.Lens.Grammar.Internal.Orphanage: instance (Data.Profunctor.Unsafe.Profunctor p, GHC.Base.Alternative (p a)) => GHC.Base.Alternative (Data.Profunctor.Yoneda.Yoneda p a)
+ Control.Lens.Grammar.Internal.Orphanage: instance (Data.Profunctor.Unsafe.Profunctor p, GHC.Base.Alternative (p a), GHC.Base.Applicative f) => GHC.Base.Alternative (Control.Lens.Internal.Profunctor.WrappedPafb f p a)
+ Control.Lens.Grammar.Internal.Orphanage: instance (Data.Profunctor.Unsafe.Profunctor p, GHC.Base.Applicative (p a)) => GHC.Base.Applicative (Data.Profunctor.Yoneda.Coyoneda p a)
+ Control.Lens.Grammar.Internal.Orphanage: instance (Data.Profunctor.Unsafe.Profunctor p, GHC.Base.Applicative (p a)) => GHC.Base.Applicative (Data.Profunctor.Yoneda.Yoneda p a)
+ Control.Lens.Grammar.Internal.Orphanage: instance (Data.Profunctor.Unsafe.Profunctor p, GHC.Base.Applicative (p a), GHC.Base.Applicative f) => GHC.Base.Applicative (Control.Lens.Internal.Profunctor.WrappedPafb f p a)
+ Control.Lens.Grammar.Internal.Orphanage: instance (Data.Profunctor.Unsafe.Profunctor p, GHC.Base.Functor (p a), Witherable.Filterable f) => Witherable.Filterable (Control.Lens.Internal.Profunctor.WrappedPafb f p a)
+ Control.Lens.Grammar.Internal.Orphanage: instance (Data.Profunctor.Unsafe.Profunctor p, GHC.Base.Functor f) => GHC.Base.Functor (Control.Lens.Internal.Profunctor.WrappedPafb f p a)
+ Control.Lens.Grammar.Internal.Orphanage: instance (Data.Profunctor.Unsafe.Profunctor p, Witherable.Filterable (p a)) => Witherable.Filterable (Data.Profunctor.Yoneda.Coyoneda p a)
+ Control.Lens.Grammar.Internal.Orphanage: instance (Data.Profunctor.Unsafe.Profunctor p, Witherable.Filterable (p a)) => Witherable.Filterable (Data.Profunctor.Yoneda.Yoneda p a)
+ Control.Lens.Grammar.Internal.Orphanage: instance (Data.Profunctor.Unsafe.Profunctor p, Witherable.Filterable f) => Data.Profunctor.Choice.Cochoice (Control.Lens.Internal.Profunctor.WrappedPafb f p)
+ Control.Lens.Grammar.Internal.Orphanage: instance (GHC.Base.Applicative f, GHC.Base.Applicative (p a)) => GHC.Base.Applicative (Data.Profunctor.Cayley.Cayley f p a)
+ Control.Lens.Grammar.Internal.Orphanage: instance (GHC.Base.Functor f, GHC.Base.Functor (p a)) => GHC.Base.Functor (Data.Profunctor.Cayley.Cayley f p a)
+ Control.Lens.Grammar.Internal.Orphanage: instance (forall x. GHC.Base.Applicative (p x), Data.Profunctor.Unsafe.Profunctor p, GHC.Base.Applicative (q a), Data.Profunctor.Unsafe.Profunctor q) => GHC.Base.Applicative (Data.Profunctor.Composition.Procompose p q a)
+ Control.Lens.Grammar.Internal.Orphanage: instance (forall x. GHC.Base.Applicative (p x), forall x. GHC.Base.Applicative (q x)) => GHC.Base.Applicative (Data.Bifunctor.Product.Product p q a)
+ Control.Lens.Grammar.Internal.Orphanage: instance Control.Arrow.Arrow p => Data.Profunctor.Unsafe.Profunctor (Control.Applicative.WrappedArrow p)
+ Control.Lens.Grammar.Internal.Orphanage: instance Control.Arrow.Arrow p => GHC.Base.Applicative (Data.Profunctor.Types.WrappedArrow p a)
+ Control.Lens.Grammar.Internal.Orphanage: instance Control.Arrow.Arrow p => GHC.Base.Functor (Data.Profunctor.Types.WrappedArrow p a)
+ Control.Lens.Grammar.Internal.Orphanage: instance Control.Monad.Fail.MonadFail m => Control.Monad.Fail.MonadFail (Data.Bifunctor.Joker.Joker m a)
+ Control.Lens.Grammar.Internal.Orphanage: instance Data.Functor.Contravariant.Divisible.Decidable f => GHC.Base.Applicative (Data.Bifunctor.Clown.Clown f a)
+ Control.Lens.Grammar.Internal.Orphanage: instance GHC.Base.Alternative f => GHC.Base.Alternative (Data.Bifunctor.Joker.Joker f a)
+ Control.Lens.Grammar.Internal.Orphanage: instance GHC.Base.Applicative (Control.Lens.Internal.Prism.Market a b s)
+ Control.Lens.Grammar.Internal.Orphanage: instance GHC.Base.Applicative f => GHC.Base.Applicative (Data.Bifunctor.Joker.Joker f a)
+ Control.Lens.Grammar.Internal.Orphanage: instance GHC.Base.Monad m => GHC.Base.Monad (Data.Bifunctor.Joker.Joker m a)
+ Control.Lens.Grammar.Internal.Orphanage: instance GHC.Base.MonadPlus m => GHC.Base.MonadPlus (Data.Bifunctor.Joker.Joker m a)
+ Control.Lens.Grammar.Internal.Orphanage: instance GHC.Base.Monoid r => GHC.Base.Applicative (Data.Profunctor.Types.Forget r a)
+ Control.Lens.Grammar.Internal.Orphanage: instance Witherable.Filterable (Data.Profunctor.Types.Forget r a)
+ Control.Lens.Grammar.Internal.Orphanage: instance Witherable.Filterable Text.ParserCombinators.ReadP.ReadP
+ Control.Lens.Grammar.Internal.Orphanage: instance Witherable.Filterable f => Data.Profunctor.Choice.Cochoice (Data.Bifunctor.Joker.Joker f)
+ Control.Lens.Grammar.Internal.Orphanage: instance Witherable.Filterable f => Witherable.Filterable (Data.Bifunctor.Joker.Joker f a)
+ Control.Lens.Grammar.Internal.Orphanage: instance Witherable.Filterable f => Witherable.Filterable (Data.Profunctor.Types.Star f a)
+ Control.Lens.Grammar.Kleene: instance Control.Lens.Grammar.Kleene.TokenAlgebra GHC.Types.Char (Text.ParserCombinators.ReadP.ReadP GHC.Types.Char)
+ Control.Lens.Grammar.Kleene: instance Control.Lens.Grammar.Kleene.TokenAlgebra token (f token) => Control.Lens.Grammar.Kleene.TokenAlgebra token (Data.Bifunctor.Joker.Joker f token token)
+ Control.Lens.Grammar.Symbol: instance Control.Lens.Grammar.Symbol.TerminalSymbol GHC.Types.Char (Text.ParserCombinators.ReadP.ReadP ())
+ Control.Lens.Grammar.Symbol: instance Control.Lens.Grammar.Symbol.TerminalSymbol token (f ()) => Control.Lens.Grammar.Symbol.TerminalSymbol token (Data.Bifunctor.Joker.Joker f () ())
+ Control.Lens.Grammar.Token: instance Control.Lens.Grammar.Token.Tokenized GHC.Types.Char (Text.ParserCombinators.ReadP.ReadP GHC.Types.Char)
+ Control.Lens.Grammar.Token: instance Control.Lens.Grammar.Token.Tokenized token (f token) => Control.Lens.Grammar.Token.Tokenized token (Data.Bifunctor.Joker.Joker f token token)
+ Control.Monad.Fail.Try: catMaybes :: Filterable f => f (Maybe a) -> f a
+ Control.Monad.Fail.Try: class Functor f => Filterable (f :: Type -> Type)
+ Control.Monad.Fail.Try: drain :: Filterable f => f a -> f b
+ Control.Monad.Fail.Try: filter :: Filterable f => (a -> Bool) -> f a -> f a
+ Control.Monad.Fail.Try: instance Control.Monad.Fail.Try.MonadTry Text.ParserCombinators.ReadP.ReadP
+ Control.Monad.Fail.Try: instance Control.Monad.Fail.Try.MonadTry m => Control.Monad.Fail.Try.MonadTry (Data.Bifunctor.Joker.Joker m a)
+ Control.Monad.Fail.Try: mapMaybe :: Filterable f => (a -> Maybe b) -> f a -> f b
+ Data.Profunctor.Distributor: instance GHC.Base.Alternative f => Data.Profunctor.Distributor.Alternator (Data.Bifunctor.Joker.Joker f)
+ Data.Profunctor.Filtrator: instance Witherable.Filterable f => Data.Profunctor.Filtrator.Filtrator (Data.Bifunctor.Joker.Joker f)
+ Data.Profunctor.Grammar: instance (GHC.Base.Alternative m, GHC.Base.Monad m, Witherable.Filterable m) => Control.Monad.Fail.Try.MonadTry (Data.Profunctor.Grammar.Parsor s m a)
+ Data.Profunctor.Grammar: instance (GHC.Base.Alternative m, GHC.Base.Monad m, Witherable.Filterable m) => Control.Monad.Fail.Try.MonadTry (Data.Profunctor.Grammar.Printor s m a)
+ Data.Profunctor.Grammar.Parsector: ParsecFailure :: TokenClass (Item s) -> [Tree String] -> ParsecFailure s
+ Data.Profunctor.Grammar.Parsector: [parsecFailure] :: ParsecState s a -> ParsecFailure s
+ Data.Profunctor.Grammar.Parsector: data ParsecFailure s
+ Data.Profunctor.Grammar.Parsector: instance (Control.Lens.Grammar.Token.Categorized (GHC.IsList.Item s), GHC.Read.Read (GHC.IsList.Item s), GHC.Read.Read (Control.Lens.Grammar.Token.Categorize (GHC.IsList.Item s))) => GHC.Read.Read (Data.Profunctor.Grammar.Parsector.ParsecFailure s)
+ Data.Profunctor.Grammar.Parsector: instance (Control.Lens.Grammar.Token.Categorized (GHC.IsList.Item s), GHC.Show.Show (GHC.IsList.Item s), GHC.Show.Show (Control.Lens.Grammar.Token.Categorize (GHC.IsList.Item s))) => GHC.Show.Show (Data.Profunctor.Grammar.Parsector.ParsecFailure s)
+ Data.Profunctor.Grammar.Parsector: instance Control.Lens.Grammar.Token.Categorized (GHC.IsList.Item s) => GHC.Base.Monoid (Data.Profunctor.Grammar.Parsector.ParsecFailure s)
+ Data.Profunctor.Grammar.Parsector: instance Control.Lens.Grammar.Token.Categorized (GHC.IsList.Item s) => GHC.Base.Semigroup (Data.Profunctor.Grammar.Parsector.ParsecFailure s)
+ Data.Profunctor.Grammar.Parsector: instance Control.Lens.Grammar.Token.Categorized (GHC.IsList.Item s) => GHC.Classes.Eq (Data.Profunctor.Grammar.Parsector.ParsecFailure s)
+ Data.Profunctor.Grammar.Parsector: instance Control.Lens.Grammar.Token.Categorized (GHC.IsList.Item s) => GHC.Classes.Ord (Data.Profunctor.Grammar.Parsector.ParsecFailure s)
- Control.Lens.Grammar: type CtxGrammar token a = forall p. (Lexical token p, forall x. BackusNaurForm (p x x), Alternator p, Filtrator p, MonadicTry p) => p a a
+ Control.Lens.Grammar: type CtxGrammar token a = forall p. (Lexical token p, Alternator p, Filtrator p, MonadicTry p) => p a a
- Control.Lens.Grammar.Symbol: terminal :: (TerminalSymbol token s, p () () ~ s, Tokenized token (p token token), Monoidal p, Cochoice p) => [token] -> s
+ Control.Lens.Grammar.Symbol: terminal :: (TerminalSymbol token s, p () () ~ s, Tokenized token (p token token), Monoidal p, Choice p, Cochoice p) => [token] -> s
- Control.Monad.Fail.Try: class (MonadFail m, MonadPlus m) => MonadTry m
+ Control.Monad.Fail.Try: class (MonadFail m, MonadPlus m, Filterable m, forall x. BackusNaurForm (m x)) => MonadTry m
- Data.Profunctor.Grammar.Parsector: ParsecState :: !Bool -> !Word -> s -> ParsecError s -> Maybe a -> ParsecState s a
+ Data.Profunctor.Grammar.Parsector: ParsecState :: !Bool -> !Word -> s -> ParsecFailure s -> Maybe a -> ParsecState s a
- Data.Profunctor.Grammar.Parsector: [parsecExpect] :: ParsecError s -> TokenClass (Item s)
+ Data.Profunctor.Grammar.Parsector: [parsecExpect] :: ParsecFailure s -> TokenClass (Item s)
- Data.Profunctor.Grammar.Parsector: [parsecLabels] :: ParsecError s -> [Tree String]
+ Data.Profunctor.Grammar.Parsector: [parsecLabels] :: ParsecFailure s -> [Tree String]

Files

CHANGELOG.md view
@@ -1,12 +1,34 @@ # Changelog for `distributors` +## 0.5.0.0 - 2026-04-16++### Changes++- `MonadTry` now implies `BackusNaurForm` (so `rule` tracing/failure semantics are available)+  and `Filtrator` (via `MonadPlus`, with `filtrate = mfiltrate`).+- Simplified the default implementation of `terminal`.+- Added `applicativeG` and `monadG` generators via `Joker` orphan and non-orphan instances.+- Made nomenclature consistent with use of "fail" and "failure", not "error".++### Internal++- Moved orphan instances and Template Haskell internals to `Control.Lens.Grammar.Internal`.++### Documentation++- Expanded `BackusNaurForm` documentation with separate motivation from:+  category-theoretic structure and failure-tracing semantics (both called “trace”+  in different senses, and combined by BNF-style rules).+- Added a `monadG` Megaparsec example.+- Fixed typo in the `makeNestedPrisms` example.+ ## 0.4.0.0 - 2026-04-10  ### New Modules  - `Control.Monad.Fail.Try` - `MonadTry` class with `try` & `fail` for backtracking parsers-- `Data.Profunctor.Grammar.Parsector` - Invertible LL(1) parser with Parsec-style error reporting:-  `ParsecState`, `ParsecError`, `parsecP`, `unparsecP`; implements hints, LL(1) commitment+- `Data.Profunctor.Grammar.Parsector` - Invertible LL(1) parser with Parsec-style failure reporting:+  `ParsecState`, `ParsecFailure`, `parsecP`, `unparsecP`; implements hints, LL(1) commitment   via `parsecLooked`, and `try` for explicit backtracking - `Data.Profunctor.Separator` - Separator/delimiter combinators: `sepWith`, `noSep`,   `beginWith`, `endWith`, `several`, `several1`, `intercalateP`, `chain`, `chain1`
distributors.cabal view
@@ -5,7 +5,7 @@ -- see: https://github.com/sol/hpack  name:           distributors-version:        0.4.0.0+version:        0.5.0.0 synopsis:       Unifying Parsers, Printers & Grammars description:    Distributors provides mathematically inspired abstractions for coders to write parsers that can also be inverted to printers. category:       Profunctors, Optics, Parsing@@ -33,11 +33,12 @@       Control.Lens.Grammar       Control.Lens.Grammar.BackusNaur       Control.Lens.Grammar.Boole+      Control.Lens.Grammar.Internal.NestedPrismTH+      Control.Lens.Grammar.Internal.Orphanage       Control.Lens.Grammar.Kleene       Control.Lens.Grammar.Symbol       Control.Lens.Grammar.Token       Control.Lens.Grate-      Control.Lens.Internal.NestedPrismTH       Control.Lens.Monocle       Control.Lens.PartialIso       Control.Lens.Wither@@ -186,6 +187,7 @@     , doctest >=0.18 && <1     , hspec >=2.7 && <3     , lens >=5.0 && <6+    , megaparsec >=9.0 && <10     , mtl >=2.2 && <3     , profunctors >=5.6 && <6     , tagged >=0.8 && <1
src/Control/Lens/Bifocal.hs view
@@ -59,8 +59,7 @@   (Alternator p, Filtrator p, Alternative f, Filterable f)     => p a (f b) -> p s (f t) -{- | If you see `ABifocal` in a signature for a function,-the function is expecting a `Bifocal`. -}+{- | `ABifocal` is monomorphically a `Bifocal`. -} type ABifocal s t a b =   Binocular a b a (Maybe b) -> Binocular a b s (Maybe t) 
src/Control/Lens/Grammar.hs view
@@ -23,6 +23,7 @@   , RegBnf (..)   , regbnfG   , regbnfGrammar+  , applicativeG     -- * Context-sensitive grammar   , CtxGrammar   , printG@@ -30,6 +31,8 @@   , unparseG   , parsecG   , unparsecG+  , readG+  , monadG     -- * Utility   , putStringLn     -- * Re-exports@@ -44,6 +47,7 @@ import Control.Lens.Grammar.Kleene import Control.Lens.Grammar.Token import Control.Lens.Grammar.Symbol+import Data.Bifunctor.Joker import Data.Maybe hiding (mapMaybe) import Data.Monoid import Data.Profunctor.Distributor@@ -56,6 +60,7 @@ import Data.String import GHC.Exts import Prelude hiding (filter)+import Text.ParserCombinators.ReadP (ReadP, readP_to_S) import Witherable  -- Re-exports@@ -94,7 +99,7 @@  We'd like to define an optic @_SemVer@, corresponding to the constructor pattern @SemVer@.-You _could_ generate it with the TemplateHaskell combinator,+You could generate it with the TemplateHaskell combinator, `makeNestedPrisms`.  @makeNestedPrisms ''SemVer@@@ -275,8 +280,8 @@ -} type Grammar token a = forall p.   ( Lexical token p-  , forall x. BackusNaurForm (p x x)   , Alternator p+  , forall x. BackusNaurForm (p x x)   ) => p a a  {- | For context-sensitivity,@@ -358,7 +363,7 @@ unrestricted filtration of grammars by computable predicates, which can recognize the larger class of recursively enumerable languages. -Finally, `CtxGrammar`s support error reporting and backtracking.+Finally, `CtxGrammar`s support failure reporting and backtracking. This has no effect on `printG`, `parseG` or `unparseG`; but it effects `parsecG` and `unparsecG`. For context, an @LL@ grammar can be (un)parsed by an @LL@ parser.@@ -373,18 +378,17 @@ diverge if the `CtxGrammar` they're run on is left-recursive.  >>> parsecG (rule "foo" (fail "bar") <|> fail "baz") "abc"-ParsecState {parsecLooked = False, parsecOffset = 0, parsecStream = "abc", parsecError = ParsecError {parsecExpect = TokenClass (OneOf (fromList "")), parsecLabels = [Node {rootLabel = "foo", subForest = [Node {rootLabel = "bar", subForest = []}]},Node {rootLabel = "baz", subForest = []}]}, parsecResult = Nothing}+ParsecState {parsecLooked = False, parsecOffset = 0, parsecStream = "abc", parsecFailure = ParsecFailure {parsecExpect = TokenClass (OneOf (fromList "")), parsecLabels = [Node {rootLabel = "foo", subForest = [Node {rootLabel = "bar", subForest = []}]},Node {rootLabel = "baz", subForest = []}]}, parsecResult = Nothing}  >>> parsecG (manyP (token 'a') >*< asIn @Char DecimalNumber) "aaab"-ParsecState {parsecLooked = True, parsecOffset = 3, parsecStream = "b", parsecError = ParsecError {parsecExpect = TokenClass (Alternate (TokenClass (OneOf (fromList "a"))) (TokenClass (NotOneOf (fromList "") (AndAsIn DecimalNumber)))), parsecLabels = []}, parsecResult = Nothing}+ParsecState {parsecLooked = True, parsecOffset = 3, parsecStream = "b", parsecFailure = ParsecFailure {parsecExpect = TokenClass (Alternate (TokenClass (OneOf (fromList "a"))) (TokenClass (NotOneOf (fromList "") (AndAsIn DecimalNumber)))), parsecLabels = []}, parsecResult = Nothing}  >>> unparsecG (tokens "abc") "abx" ""-ParsecState {parsecLooked = True, parsecOffset = 2, parsecStream = "ab", parsecError = ParsecError {parsecExpect = TokenClass (OneOf (fromList "c")), parsecLabels = []}, parsecResult = Nothing}+ParsecState {parsecLooked = True, parsecOffset = 2, parsecStream = "ab", parsecFailure = ParsecFailure {parsecExpect = TokenClass (OneOf (fromList "c")), parsecLabels = []}, parsecResult = Nothing}  -} type CtxGrammar token a = forall p.   ( Lexical token p-  , forall x. BackusNaurForm (p x x)   , Alternator p   , Filtrator p   , MonadicTry p@@ -768,8 +772,8 @@ regbnfGrammar = rule "regbnf" $ _RegBnf . _Bnf >~   terminal "{start} = " >* regexGrammar >*< several noSep     (terminal "\n" >* nonterminalG *< terminal " = " >*< regexGrammar)-       + {- | `regstringG` generates a `RegString` from a regular grammar. Since context-free `Grammar`s and `CtxGrammar`s aren't necessarily regular, the type system will prevent `regstringG` from being applied to them.@@ -841,7 +845,7 @@ Running the parser on an input string value `uncons`es tokens from the beginning of an input string from left to right, returning `parsecResult` as `Nothing` on failure or `Just`-an output syntax value, with parse failure stored in `parsecError`,+an output syntax value, with parse failure stored in `parsecFailure`, and a remaining output `parsecStream`. -} parsecG@@ -870,6 +874,77 @@   -> ParsecState string a unparsecG parsector = unparsecP parsector +{- | Generate any `Applicative` parser backend+from a `Grammar` with `applicativeG`.+It works the same way as `monadG`,+for parsers without `Monad` instances.+That permits backends to use algorithms+that can only parse context-free `Grammar`s.+-}+applicativeG+  :: ( Alternative f+     , TokenAlgebra token (f token)+     , TerminalSymbol token (f ())+     , forall x. BackusNaurForm (f x)+     )+  => Grammar token a -- ^ context-free grammar+  -> f a+applicativeG joker = runJoker joker++{- | Generate a `ReadP` backend from a `CtxGrammar` `Char`. -}+readG :: CtxGrammar Char a -> ReadP a+readG joker = monadG joker++{- | Generate any parser `Monad` backend+from a `CtxGrammar` with `monadG`.+Let's see how to do this without orphan instances,+using the Megaparsec library.++@+import qualified Text.Megaparsec as M+import qualified Text.Megaparsec.Char as M+import Control.Lens.Grammar++newtype WrapMega a = WrapMega {unwrapMega :: M.Parsec String String a}+  deriving newtype+    ( Functor, Applicative, Alternative+    , Monad, MonadPlus, MonadFail+    )+instance TerminalSymbol Char (WrapMega ()) where+  terminal str = WrapMega (M.chunk str *> pure ())+instance TokenAlgebra Char (WrapMega Char) where+  tokenClass exam = WrapMega $ M.label (show exam) (M.satisfy (tokenClass exam))+instance Tokenized Char (WrapMega Char) where+  anyToken = WrapMega M.anySingle+  token = WrapMega . M.single+  oneOf = WrapMega . M.oneOf+  notOneOf = WrapMega . M.noneOf+  asIn cat = WrapMega $ M.label ("in category " ++ show cat) (M.satisfy (asIn cat))+  notAsIn cat = WrapMega $ M.label ("not in category " ++ show cat) (M.satisfy (notAsIn cat))+instance BackusNaurForm (WrapMega a) where+  rule lbl (WrapMega p) = WrapMega (M.label lbl p)+  ruleRec lbl = rule lbl . fix+instance Filterable WrapMega where+  catMaybes m = m >>= maybe (fail "unrestricted filtration") pure+instance MonadTry WrapMega where+  try (WrapMega p) = WrapMega (M.try p)++megaparsecG+  :: CtxGrammar Char a+  -> M.Parsec String String a+megaparsecG gram = unwrapMega (monadG gram)+@++-}+monadG+  :: ( MonadTry m+     , TokenAlgebra token (m token)+     , TerminalSymbol token (m ())+     )+  => CtxGrammar token a -- ^ context-sensitive grammar+  -> m a+monadG joker = runJoker joker+ {- | `putStringLn` is a utility that generalizes `putStrLn` to string-like interfaces such as `RegString` and `RegBnf`. -}@@ -882,7 +957,7 @@     = fromMaybe zeroK     . listToMaybe     . mapMaybe prsF-    . parseP regexGrammar+    . readP_to_S (readG regexGrammar)     where       prsF (rex,"") = Just rex       prsF _ = Nothing@@ -901,7 +976,7 @@     = fromMaybe zeroK     . listToMaybe     . mapMaybe prsF-    . parseP regbnfGrammar+    . readP_to_S (readG regbnfGrammar)     where       prsF (regbnf,"") = Just regbnf       prsF _ = Nothing
src/Control/Lens/Grammar/BackusNaur.hs view
@@ -29,35 +29,64 @@ import Control.Lens.Grammar.Kleene import Control.Lens.Grammar.Token import Control.Lens.Grammar.Symbol+import Data.Bifunctor.Joker import Data.Coerce import Data.Foldable import Data.Function import Data.MemoTrie import qualified Data.Set as Set import Data.Set (Set)+import Text.ParserCombinators.ReadP (ReadP) -{- | `BackusNaurForm` grammar combinators formalize-`rule` abstraction and general recursion. Both context-free-`Control.Lens.Grammar.Grammar`s & `Control.Lens.Grammar.CtxGrammar`s-support the `BackusNaurForm` interface.+{- | `BackusNaurForm` grammar combinators formalize traced+`rule` abstraction and general recursion with `ruleRec`,+related by this invariant. -prop> rule name bnf = ruleRec name (\_ -> bnf)+prop> rule label bnf = ruleRec label (\_ -> bnf) +The `BackusNaurForm` interface is reminiscent of+two distinct notions of "trace".+First as a [traced Cartesian monoidal category]+(https://ncatlab.org/nlab/show/traced+monoidal+category#in_cartesian_monoidal_categories)+which models general recursion abstractly,+and second as a `Debug.Trace.trace`-like label for `rule` abstraction.+The category @(->)@ already has a traced @(,)@-monoidal structure+in the form of `Data.Profunctor.unfirst` @=@ `Control.Arrow.loop`+or equivalently the fixpoint function `fix`,+determining default methods for a `BackusNaurForm`.++prop> rule _ = id+prop> ruleRec _ = fix++The `BackusNaurForm` interface permits overloading these methods,+and tracing them with a label.++Both context-free `Control.Lens.Grammar.Grammar`s+& `Control.Lens.Grammar.CtxGrammar`s+support the `BackusNaurForm` interface. See Breitner, [Showcasing Applicative]-(https://www.joachim-breitner.de/blog/710-Showcasing_Applicative).+(https://www.joachim-breitner.de/blog/710-Showcasing_Applicative),+for the original interface.+ -} class BackusNaurForm bnf where -  {- | Rule abstraction, `rule` can be used to detail parse errors. -}+  {- | Rule abstraction. -}   rule :: String -> bnf -> bnf   rule _ = id -  {- | General recursion, using `ruleRec`, rules can refer to themselves. -}+  {- | General recursion. -}   ruleRec :: String -> (bnf -> bnf) -> bnf   ruleRec _ = fix  {- | A `Bnf` consists of a distinguished starting rule-and a set of named rules, supporting the `BackusNaurForm` interface. -}+and a set of named rules. When a `Bnf` supports `NonTerminalSymbol`s,+then it supports the `BackusNaurForm` interface+by replacing recursive calls with `nonTerminal`s.++prop> ruleRec label f = rule label (f (nonTerminal label))++-} data Bnf rule = Bnf   { startBnf :: rule   , rulesBnf :: Set (String, rule)@@ -145,14 +174,14 @@ -- instances instance (Ord rule, NonTerminalSymbol rule)   => BackusNaurForm (Bnf rule) where-    rule name = ruleRec name . const-    ruleRec name f =-      let-        newStart = nonTerminal name-        Bnf newRule oldRules = f (Bnf newStart mempty)-        newRules = Set.insert (name, newRule) oldRules-      in-        Bnf newStart newRules+    rule label (Bnf newRule oldRules) = (nonTerminal label)+      {rulesBnf = Set.insert (label, newRule) oldRules}+    ruleRec label f = rule label (f (nonTerminal label))+instance (forall x. BackusNaurForm (f x))+  => BackusNaurForm (Joker f a b) where+    rule name = Joker . rule name . runJoker+    ruleRec name = Joker . ruleRec name . dimap Joker runJoker+instance BackusNaurForm (ReadP a) instance (Ord rule, TerminalSymbol token rule)   => TerminalSymbol token (Bnf rule) where   terminal = liftBnf0 . terminal
src/Control/Lens/Grammar/Boole.hs view
@@ -1,6 +1,6 @@ {- | Module      : Control.Lens.Grammar.Boole-Description : Boolean algebras & token classes+Description : Boolean algebras Copyright   : (C) 2026 - Eitan Chatav License     : BSD-style (see the file LICENSE) Maintainer  : Eitan Chatav <eitan.chatav@gmail.com>@@ -9,7 +9,6 @@  See Boole, [The Mathematical Analysis of Logic] (https://www.gutenberg.org/files/36884/36884-pdf.pdf).-Categorized token classes form a Boolean algebra. -}  module Control.Lens.Grammar.Boole
+ src/Control/Lens/Grammar/Internal/NestedPrismTH.hs view
@@ -0,0 +1,342 @@+{- |+Module      : Control.Lens.Grammar.Internal.NestedPrismTH+Description : nested pair prisms+Copyright   : (C) 2026 - Eitan Chatav+License     : BSD-style (see the file LICENSE)+Maintainer  : Eitan Chatav <eitan.chatav@gmail.com>+Stability   : provisional+Portability : non-portable++Code is duplicated from `Control.Lens.Internal.PrismTH`,+with small tweaks to support nested pairs.+-}++module Control.Lens.Grammar.Internal.NestedPrismTH+  ( -- * Nested prisms+    makeNestedPrisms+  ) where++import Control.Applicative+import Control.Lens.Getter+import Control.Lens.Internal.TH+import Control.Lens.Lens+import Control.Monad+import Data.Char (isUpper)+import qualified Data.List as List+import Data.Set.Lens+import Data.Traversable+import Language.Haskell.TH+import qualified Language.Haskell.TH.Datatype as D+import Language.Haskell.TH.Lens+import qualified Data.Map as Map+import qualified Data.Set as Set+import Data.Set (Set)+import Prelude++-- | Similar to `Control.Lens.Internal.PrismTH.makePrisms`,+-- `makeNestedPrisms` generates a `Control.Lens.Prism.Prism`+-- for each constructor of a data type.+-- `Control.Lens.Iso.Iso`s are generated when possible.+-- `Control.Lens.Review.Review`s are generated for constructors+-- with existentially quantified constructors and GADTs.+-- The difference in `makeNestedPrisms`+-- is that constructors with @n > 2@ arguments+-- will use right-nested pairs, rather than a flat @n@-tuple.+-- This makes them suitable for pattern bonding,+-- by use of the applicator `Control.Lens.PartialIso.>?`+-- to `Data.Profunctor.Monoidal.Monoidal` idiom notation+-- with `Data.Profunctor.Monoidal.>*<`,+-- or to `Data.Profunctor.Monadic.Monadic` qualified do-notation.+--+-- /e.g./+--+-- @+-- data FooBar a+--   = Foo a+--   | Bar Int+--   | Baz Int Char+--   | Buzz Double String Bool+--   | Boop+-- makeNestedPrisms ''FooBar+-- @+--+-- will create+--+-- @+-- _Foo :: Prism (FooBar a) (FooBar b) a b+-- _Bar :: Prism' (FooBar a) Int+-- _Baz :: Prism' (FooBar a) (Int, Char)+-- _Buzz :: Prism' (FooBar a) (Double, (String, Bool))+-- _Boop :: Prism' (FooBar a) ()+-- @+makeNestedPrisms :: Name -> DecsQ+makeNestedPrisms typeName =+  do info <- D.reifyDatatype typeName+     let cons = D.datatypeCons info+     makeConsPrisms (datatypeTypeKinded info) (map normalizeCon cons)++-- Generate prisms for the given type, and normalized constructors.+-- This function dispatches between Iso generation, and normal top-level+makeConsPrisms :: Type -> [NCon] -> DecsQ+-- special case: single constructor -> make iso+makeConsPrisms t [con@(NCon _ [] [] _)] = makeConIso t con+-- top-level definitions+makeConsPrisms t cons =+  fmap concat $ for cons $ \con ->+    do let conName = view nconName con+       stab <- computeOpticType t cons con+       let n = prismName conName+       sequenceA+         ( [ sigD n (return (quantifyType [] (stabToType Set.empty stab)))+           , valD (varP n) (normalB (makeConOpticExp stab cons con)) []+           ]+           ++ inlinePragma n+         )++data OpticType = PrismType | ReviewType++data Stab  = Stab Cxt OpticType Type Type Type Type++stabSimple :: Stab -> Bool+stabSimple (Stab _ _ s t a b) = s == t && a == b++stabToType :: Set Name -> Stab -> Type+stabToType clsTVBNames stab@(Stab cx ty s t a b) =+  quantifyType' clsTVBNames cx stabTy+  where+  stabTy =+    case ty of+      PrismType  | stabSimple stab -> prism'TypeName  `conAppsT` [t,b]+                 | otherwise       -> prismTypeName   `conAppsT` [s,t,a,b]+      ReviewType                   -> reviewTypeName  `conAppsT` [t,b]++stabType :: Stab -> OpticType+stabType (Stab _ o _ _ _ _) = o++computeOpticType :: Type -> [NCon] -> NCon -> Q Stab+computeOpticType t cons con =+  do let cons' = List.delete con cons+     if null (_nconVars con)+         then computePrismType t (view nconCxt con) cons' con+         else computeReviewType t (view nconCxt con) (view nconTypes con)++computeReviewType :: Type -> Cxt -> [Type] -> Q Stab+computeReviewType s' cx tys =+  do let t = s'+     s <- fmap VarT (newName "s")+     a <- fmap VarT (newName "a")+     b <- toNestedPairT (map return tys)+     return (Stab cx ReviewType s t a b)++-- Compute the full type-changing Prism type given an outer type,+-- list of constructors, and target constructor name. Additionally+-- return 'True' if the resulting type is a "simple" prism.+computePrismType :: Type -> Cxt -> [NCon] -> NCon -> Q Stab+computePrismType t cx cons con =+  do let ts      = view nconTypes con+         unbound = setOf typeVars t Set.\\ setOf typeVars cons+     sub <- sequenceA (Map.fromSet (newName . nameBase) unbound)+     b   <- toNestedPairT (map return ts)+     a   <- toNestedPairT (map return (substTypeVars sub ts))+     let s = substTypeVars sub t+     return (Stab cx PrismType s t a b)++computeIsoType :: Type -> [Type] -> TypeQ+computeIsoType t' fields =+  do sub <- sequenceA (Map.fromSet (newName . nameBase) (setOf typeVars t'))+     let t = return                    t'+         s = return (substTypeVars sub t')+         b = toNestedPairT (map return                    fields)+         a = toNestedPairT (map return (substTypeVars sub fields))+         ty | Map.null sub = appsT (conT iso'TypeName) [t,b]+            | otherwise    = appsT (conT isoTypeName) [s,t,a,b]+     quantifyType [] <$> ty++-- Construct either a Review or Prism as appropriate+makeConOpticExp :: Stab -> [NCon] -> NCon -> ExpQ+makeConOpticExp stab cons con =+  case stabType stab of+    PrismType  -> makeConPrismExp stab cons con+    ReviewType -> makeConReviewExp con++-- Construct an iso declaration+makeConIso :: Type -> NCon -> DecsQ+makeConIso s con =+  do let ty      = computeIsoType s (view nconTypes con)+         defName = prismName (view nconName con)+     sequenceA+       ( [ sigD       defName  ty+         , valD (varP defName) (normalB (makeConIsoExp con)) []+         ] +++         inlinePragma defName+       )++-- Construct prism expression+--+-- prism <<reviewer>> <<remitter>>+makeConPrismExp ::+  Stab ->+  [NCon] {- ^ constructors       -} ->+  NCon   {- ^ target constructor -} ->+  ExpQ+makeConPrismExp stab cons con = appsE [varE prismValName, reviewer, remitter]+  where+  ts = view nconTypes con+  fields  = length ts+  conName = view nconName con+  reviewer                   = makeReviewer       conName fields+  remitter | stabSimple stab = makeSimpleRemitter conName (length cons) fields+           | otherwise       = makeFullRemitter cons conName++-- Construct an Iso expression+--+-- iso <<reviewer>> <<remitter>>+makeConIsoExp :: NCon -> ExpQ+makeConIsoExp con = appsE [varE isoValName, remitter, reviewer]+  where+  conName = view nconName con+  fields  = length (view nconTypes con)+  reviewer = makeReviewer    conName fields+  remitter = makeIsoRemitter conName fields++-- Construct a Review expression+--+-- unto (\(x,y,z) -> Con x y z)+makeConReviewExp :: NCon -> ExpQ+makeConReviewExp con = appE (varE untoValName) reviewer+  where+  conName = view nconName con+  fields  = length (view nconTypes con)+  reviewer = makeReviewer conName fields++------------------------------------------------------------------------+-- Prism and Iso component builders+------------------------------------------------------------------------++-- Construct the review portion of a prism.+--+-- (\(x,y,z) -> Con x y z) :: b -> t+makeReviewer :: Name -> Int -> ExpQ+makeReviewer conName fields =+  do xs <- newNames "x" fields+     lam1E (toNestedPairP (map varP xs))+           (conE conName `appsE1` map varE xs)++-- Construct the remit portion of a prism.+-- Pattern match only target constructor, no type changing+--+-- (\x -> case s of+--          Con x y z -> Right (x,y,z)+--          _         -> Left x+-- ) :: s -> Either s a+makeSimpleRemitter ::+  Name {- The name of the constructor on which this prism focuses -} ->+  Int  {- The number of constructors the parent data type has     -} ->+  Int  {- The number of fields the constructor has                -} ->+  ExpQ+makeSimpleRemitter conName numCons fields =+  do x  <- newName "x"+     xs <- newNames "y" fields+     let matches =+           [ match (conP conName (map varP xs))+                   (normalB (appE (conE rightDataName) (toNestedPairE (map varE xs))))+                   []+           ] +++           [ match wildP (normalB (appE (conE leftDataName) (varE x))) []+           | numCons > 1 -- Only generate a catch-all case if there is at least+                         -- one constructor besides the one being focused on.+           ]+     lam1E (varP x) (caseE (varE x) matches)++-- Pattern match all constructors to enable type-changing+--+-- (\x -> case s of+--          Con x y z -> Right (x,y,z)+--          Other_n w   -> Left (Other_n w)+-- ) :: s -> Either t a+makeFullRemitter :: [NCon] -> Name -> ExpQ+makeFullRemitter cons target =+  do x <- newName "x"+     lam1E (varP x) (caseE (varE x) (map mkMatch cons))+  where+  mkMatch (NCon conName _ _ n) =+    do xs <- newNames "y" (length n)+       match (conP conName (map varP xs))+             (normalB+               (if conName == target+                  then appE (conE rightDataName) (toNestedPairE (map varE xs))+                  else appE (conE leftDataName) (conE conName `appsE1` map varE xs)))+             []++-- Construct the remitter suitable for use in an 'Iso'+--+-- (\(Con x y z) -> (x,y,z)) :: s -> a+makeIsoRemitter :: Name -> Int -> ExpQ+makeIsoRemitter conName fields =+  do xs <- newNames "x" fields+     lam1E (conP conName (map varP xs))+           (toNestedPairE (map varE xs))++------------------------------------------------------------------------+-- Utilities+------------------------------------------------------------------------++-- Normalized constructor+data NCon = NCon+  { _nconName :: Name+  , _nconVars :: [Name]+  , _nconCxt  :: Cxt+  , _nconTypes :: [Type]+  }+  deriving (Eq)+instance HasTypeVars NCon where+  typeVarsEx s f (NCon x vars y z) = NCon x vars <$> typeVarsEx s' f y <*> typeVarsEx s' f z+    where s' = List.foldl' (flip Set.insert) s vars++nconName :: Lens' NCon Name+nconName f x = fmap (\y -> x {_nconName = y}) (f (_nconName x))++nconCxt :: Lens' NCon Cxt+nconCxt f x = fmap (\y -> x {_nconCxt = y}) (f (_nconCxt x))++nconTypes :: Lens' NCon [Type]+nconTypes f x = fmap (\y -> x {_nconTypes = y}) (f (_nconTypes x))++-- Normalize a single 'Con' to its constructor name and field types.+normalizeCon :: D.ConstructorInfo -> NCon+normalizeCon info = NCon (D.constructorName info)+                         (D.tvName <$> D.constructorVars info)+                         (D.constructorContext info)+                         (D.constructorFields info)++-- Compute a prism's name by prefixing an underscore for normal+-- constructors and period for operators.+prismName ::+  Name {- type constructor        -} ->+  Name {- prism name              -}+prismName n =+  case nameBase n of+    [] -> error "prismName: empty name base?"+    nb@(x:_) | isUpper x -> mkName (prefix '_' nb)+             | otherwise -> mkName (prefix '.' nb) -- operator+  where+    prefix :: Char -> String -> String+    prefix char str = char:str++-- Construct a tuple type given a list of types.+toNestedPairT :: [TypeQ] -> TypeQ+toNestedPairT [] = appsT (tupleT 0) []+toNestedPairT [x] = x+toNestedPairT (x:xs) = appsT (tupleT 2) [x, toNestedPairT xs]++-- Construct a tuple value given a list of expressions.+toNestedPairE :: [ExpQ] -> ExpQ+toNestedPairE [] = tupE []+toNestedPairE [x] = x+toNestedPairE (x:xs) = tupE [x, toNestedPairE xs]++-- Construct a tuple pattern given a list of patterns.+toNestedPairP :: [PatQ] -> PatQ+toNestedPairP [] = tupP []+toNestedPairP [x] = x+toNestedPairP (x:xs) = tupP [x, toNestedPairP xs]
+ src/Control/Lens/Grammar/Internal/Orphanage.hs view
@@ -0,0 +1,140 @@+{-# OPTIONS_GHC -Wno-orphans #-}++{- |+Module      : Control.Lens.Grammar.Internal.Orphanage+Description : orphanage+Copyright   : (C) 2026 - Eitan Chatav+License     : BSD-style (see the file LICENSE)+Maintainer  : Eitan Chatav <eitan.chatav@gmail.com>+Stability   : provisional+Portability : non-portable++An orphanage for instances without a home.+-}++module Control.Lens.Grammar.Internal.Orphanage () where++import Control.Applicative hiding (WrappedArrow)+import Control.Applicative qualified as Ap (WrappedArrow)+import Control.Arrow+import Control.Lens+import Control.Lens.Internal.Prism+import Control.Lens.Internal.Profunctor+import Control.Monad+import Data.Bifunctor.Clown+import Data.Bifunctor.Joker+import Data.Bifunctor.Product+import Data.Distributive+import Data.Functor.Compose+import Data.Functor.Contravariant.Divisible+import Data.Profunctor hiding (WrappedArrow)+import Data.Profunctor qualified as Pro (WrappedArrow)+import Data.Profunctor.Cayley+import Data.Profunctor.Composition+import Data.Profunctor.Monad+import Data.Profunctor.Yoneda+import Text.ParserCombinators.ReadP (ReadP)+import Witherable++-- Orphanage --+instance (Profunctor p, Functor f)+  => Functor (WrappedPafb f p a) where fmap = rmap+deriving via Compose (p a) f instance+  (Profunctor p, Functor (p a), Filterable f)+    => Filterable (WrappedPafb f p a)+instance (Profunctor p, Filterable f)+  => Cochoice (WrappedPafb f p) where+    unleft (WrapPafb p) = WrapPafb $+      dimap Left (mapMaybe (either Just (const Nothing))) p+    unright (WrapPafb p) = WrapPafb $+      dimap Right (mapMaybe (either (const Nothing) Just)) p+instance (Profunctor p, Filterable (p a))+  => Filterable (Yoneda p a) where+    catMaybes = proreturn . catMaybes . proextract+instance (Profunctor p, Filterable (p a))+  => Filterable (Coyoneda p a) where+    catMaybes = proreturn . catMaybes . proextract+instance Filterable f => Filterable (Star f a) where+  catMaybes (Star f) = Star (catMaybes . f)+instance Monoid r => Applicative (Forget r a) where+  pure _ = Forget mempty+  Forget f <*> Forget g = Forget (f <> g)+instance Filterable (Forget r a) where+  catMaybes (Forget f) = Forget f+instance Decidable f => Applicative (Clown f a) where+  pure _ = Clown conquer+  Clown x <*> Clown y = Clown (divide (id &&& id) x y)+deriving newtype instance Applicative f => Applicative (Joker f a)+deriving newtype instance Alternative f => Alternative (Joker f a)+deriving newtype instance Filterable f => Filterable (Joker f a)+deriving newtype instance Monad m => Monad (Joker m a)+deriving newtype instance MonadFail m => MonadFail (Joker m a)+deriving newtype instance MonadPlus m => MonadPlus (Joker m a)+instance Filterable f => Cochoice (Joker f) where+  unleft (Joker x) = Joker+    (mapMaybe (either Just (const Nothing)) x)+  unright (Joker x) = Joker+    (mapMaybe (either (const Nothing) Just) x)+instance Filterable ReadP where+  catMaybes m = m >>= maybe empty pure+deriving via Compose (p a) f instance+  (Profunctor p, Applicative (p a), Applicative f)+    => Applicative (WrappedPafb f p a)+deriving via Compose (p a) f instance+  (Profunctor p, Alternative (p a), Applicative f)+    => Alternative (WrappedPafb f p a)+instance (Closed p, Distributive f)+  => Closed (WrappedPafb f p) where+    closed (WrapPafb p) = WrapPafb (rmap distribute (closed p))+deriving via (Ap.WrappedArrow p a) instance Arrow p+  => Functor (Pro.WrappedArrow p a)+deriving via (Ap.WrappedArrow p a) instance Arrow p+  => Applicative (Pro.WrappedArrow p a)+deriving via (Pro.WrappedArrow p) instance Arrow p+  => Profunctor (Ap.WrappedArrow p)+instance+  ( forall x. Applicative (p x), Profunctor p+  , Applicative (q a), Profunctor q+  ) => Applicative (Procompose p q a) where+    pure b = Procompose (pure b) (pure b)+    Procompose wb aw <*> Procompose vb av = Procompose+      (liftA2 ($) (lmap fst wb) (lmap snd vb))+      (liftA2 (,) aw av)+instance (forall x. Applicative (p x), forall x. Applicative (q x))+  => Applicative (Product p q a) where+    pure b = Pair (pure b) (pure b)+    Pair x0 y0 <*> Pair x1 y1 = Pair (x0 <*> x1) (y0 <*> y1)+instance (Functor f, Functor (p a)) => Functor (Cayley f p a) where+  fmap f (Cayley x) = Cayley (fmap (fmap f) x)+instance (Applicative f, Applicative (p a)) => Applicative (Cayley f p a) where+  pure b = Cayley (pure (pure b))+  Cayley x <*> Cayley y = Cayley ((<*>) <$> x <*> y)+instance (Profunctor p, Applicative (p a))+  => Applicative (Yoneda p a) where+    pure = proreturn . pure+    ab <*> cd = proreturn (proextract ab <*> proextract cd)+instance (Profunctor p, Applicative (p a))+  => Applicative (Coyoneda p a) where+    pure = proreturn . pure+    ab <*> cd = proreturn (proextract ab <*> proextract cd)+instance (Profunctor p, Alternative (p a))+  => Alternative (Yoneda p a) where+    empty = proreturn empty+    ab <|> cd = proreturn (proextract ab <|> proextract cd)+    many = proreturn . many . proextract+instance (Profunctor p, Alternative (p a))+  => Alternative (Coyoneda p a) where+    empty = proreturn empty+    ab <|> cd = proreturn (proextract ab <|> proextract cd)+    many = proreturn . many . proextract+instance Applicative (Market a b s) where+  pure t = Market (pure t) (pure (Left t))+  Market f0 g0 <*> Market f1 g1 = Market+    (\b -> f0 b (f1 b))+    (\s ->+      case g0 s of+        Left bt -> case g1 s of+          Left b -> Left (bt b)+          Right a -> Right a+        Right a -> Right a+    )
src/Control/Lens/Grammar/Kleene.hs view
@@ -1,6 +1,6 @@ {- | Module      : Control.Lens.Grammar.Kleene-Description : Kleene star algebras & regular expressions+Description : Kleene star algebras, regular expressions & token classes Copyright   : (C) 2026 - Eitan Chatav License     : BSD-style (see the file LICENSE) Maintainer  : Eitan Chatav <eitan.chatav@gmail.com>@@ -29,6 +29,7 @@ import Control.Lens.Grammar.Boole import Control.Lens.Grammar.Symbol import Control.Lens.Grammar.Token+import Data.Bifunctor.Joker import Data.Foldable import Data.MemoTrie import Data.Monoid@@ -37,6 +38,8 @@ import Data.Set (Set) import qualified Data.Set as Set import GHC.Generics+import Text.ParserCombinators.ReadP (ReadP)+import qualified Text.ParserCombinators.ReadP as ReadP  {- | A `KleeneStarAlgebra` is a ring with a generally non-commutative multiplication,@@ -217,6 +220,11 @@     NotOneOf as catTest -> RegExam (NotOneOf as catTest)     Alternate exam1 exam2 ->       RegExam (Alternate (tokenClass exam1) (tokenClass exam2))+instance TokenAlgebra token (f token)+  => TokenAlgebra token (Joker f token token) where+    tokenClass = Joker . tokenClass+instance TokenAlgebra Char (ReadP Char) where+  tokenClass = ReadP.satisfy . tokenClass instance Categorized token => Monoid (RegEx token) where   mempty = SeqEmpty instance Categorized token => Semigroup (RegEx token) where
src/Control/Lens/Grammar/Symbol.hs view
@@ -17,17 +17,26 @@ import Control.Lens import Control.Lens.PartialIso import Control.Lens.Grammar.Token+import Data.Bifunctor.Joker import Data.Profunctor import Data.Profunctor.Monoidal+import Text.ParserCombinators.ReadP (ReadP, string)  -- | A `terminal` symbol in a grammar. class TerminalSymbol token s | s -> token where   terminal :: [token] -> s   default terminal-    :: (p () () ~ s, Tokenized token (p token token), Monoidal p, Cochoice p)+    :: (p () () ~ s, Tokenized token (p token token), Monoidal p, Choice p, Cochoice p)     => [token] -> s-  terminal = foldr (\a p -> only a ?< token a *> p) oneP+  terminal str = only str ?< tokens str  -- | A `nonTerminal` symbol in a grammar. class NonTerminalSymbol s where   nonTerminal :: String -> s++-- instances+instance TerminalSymbol token (f ())+  => TerminalSymbol token (Joker f () ()) where+    terminal = Joker . terminal @token+instance TerminalSymbol Char (ReadP ()) where+  terminal str = string str *> pure ()
src/Control/Lens/Grammar/Token.hs view
@@ -20,10 +20,13 @@  import Control.Lens import Control.Lens.PartialIso+import Data.Bifunctor.Joker import Data.Char import Data.Profunctor import Data.Profunctor.Monoidal import Data.Word+import Text.ParserCombinators.ReadP (ReadP)+import qualified Text.ParserCombinators.ReadP as ReadP  {- | `Categorized` provides a type family `Categorize` and a function to `categorize` tokens into disjoint categories.@@ -96,14 +99,6 @@     => Categorize token -> p   notAsIn = satisfy . notAsIn -instance Categorized token => Tokenized token (token -> Bool) where-  anyToken _ = True-  token = (==)-  oneOf = flip elem-  notOneOf = flip notElem-  asIn = lmap categorize . (==)-  notAsIn = lmap categorize . (/=)- {- | A single token that satisfies a predicate. -} satisfy   :: (Tokenized a (p a a), Choice p, Cochoice p)@@ -118,3 +113,27 @@      )   => f a -> p s s tokens = foldr ((>:<) . token) asEmpty++-- instances+instance Categorized token => Tokenized token (token -> Bool) where+  anyToken _ = True+  token = (==)+  oneOf = flip elem+  notOneOf = flip notElem+  asIn = lmap categorize . (==)+  notAsIn = lmap categorize . (/=)+instance Tokenized token (f token)+  => Tokenized token (Joker f token token) where+    anyToken = Joker (anyToken @token)+    token = Joker . token @token+    oneOf = Joker . oneOf @token+    notOneOf = Joker . notOneOf @token+    asIn = Joker . asIn @token+    notAsIn = Joker . notAsIn @token+instance Tokenized Char (ReadP Char) where+  anyToken = ReadP.get+  token = ReadP.char+  oneOf = ReadP.satisfy . oneOf+  notOneOf = ReadP.satisfy . notOneOf+  asIn = ReadP.satisfy . asIn+  notAsIn = ReadP.satisfy . notAsIn
− src/Control/Lens/Internal/NestedPrismTH.hs
@@ -1,342 +0,0 @@-{- |-Module      : Control.Lens.Internal.NestedPrismTH-Description : nested pair prisms-Copyright   : (C) 2026 - Eitan Chatav-License     : BSD-style (see the file LICENSE)-Maintainer  : Eitan Chatav <eitan.chatav@gmail.com>-Stability   : provisional-Portability : non-portable--Code is duplicated from `Control.Lens.Internal.PrismTH`,-with small tweaks to support nested pairs.--}--module Control.Lens.Internal.NestedPrismTH-  ( -- * Nested prisms-    makeNestedPrisms-  ) where--import Control.Applicative-import Control.Lens.Getter-import Control.Lens.Internal.TH-import Control.Lens.Lens-import Control.Monad-import Data.Char (isUpper)-import qualified Data.List as List-import Data.Set.Lens-import Data.Traversable-import Language.Haskell.TH-import qualified Language.Haskell.TH.Datatype as D-import Language.Haskell.TH.Lens-import qualified Data.Map as Map-import qualified Data.Set as Set-import Data.Set (Set)-import Prelude---- | Similar to `Control.Lens.Internal.PrismTH.makePrisms`,--- `makeNestedPrisms` generates a `Control.Lens.Prism.Prism`--- for each constructor of a data type.--- `Control.Lens.Iso.Iso`s are generated when possible.--- `Control.Lens.Review.Review`s are generated for constructors--- with existentially quantified constructors and GADTs.--- The difference in `makeNestedPrisms`--- is that constructors with @n > 2@ arguments--- will use right-nested pairs, rather than a flat @n@-tuple.--- This makes them suitable for pattern bonding,--- by use of the applicator `Control.Lens.PartialIso.>?`--- to `Data.Profunctor.Monoidal.Monoidal` idiom notation--- with `Data.Profunctor.Monoidal.>*<`,--- or to `Data.Profunctor.Monadic.Monadic` qualified do-notation.------ /e.g./------ @--- data FooBar a---   = Foo a---   | Bar Int---   | Baz Int Char---   | Buzz Double String Bool---   | Boop--- makeNestedPrisms ''FooBar--- @------ will create------ @--- _Foo :: Prism (FooBarBaz a) (FooBarBaz b) a b--- _Bar :: Prism' (FooBarBaz a) Int--- _Baz :: Prism' (FooBarBaz a) (Int, Char)--- _Buzz :: Prism' (FooBarBaz a) (Double, (String, Bool))--- _Boop :: Prism' (FooBarBaz a) ()--- @-makeNestedPrisms :: Name -> DecsQ-makeNestedPrisms typeName =-  do info <- D.reifyDatatype typeName-     let cons = D.datatypeCons info-     makeConsPrisms (datatypeTypeKinded info) (map normalizeCon cons)---- Generate prisms for the given type, and normalized constructors.--- This function dispatches between Iso generation, and normal top-level-makeConsPrisms :: Type -> [NCon] -> DecsQ--- special case: single constructor -> make iso-makeConsPrisms t [con@(NCon _ [] [] _)] = makeConIso t con--- top-level definitions-makeConsPrisms t cons =-  fmap concat $ for cons $ \con ->-    do let conName = view nconName con-       stab <- computeOpticType t cons con-       let n = prismName conName-       sequenceA-         ( [ sigD n (return (quantifyType [] (stabToType Set.empty stab)))-           , valD (varP n) (normalB (makeConOpticExp stab cons con)) []-           ]-           ++ inlinePragma n-         )--data OpticType = PrismType | ReviewType--data Stab  = Stab Cxt OpticType Type Type Type Type--stabSimple :: Stab -> Bool-stabSimple (Stab _ _ s t a b) = s == t && a == b--stabToType :: Set Name -> Stab -> Type-stabToType clsTVBNames stab@(Stab cx ty s t a b) =-  quantifyType' clsTVBNames cx stabTy-  where-  stabTy =-    case ty of-      PrismType  | stabSimple stab -> prism'TypeName  `conAppsT` [t,b]-                 | otherwise       -> prismTypeName   `conAppsT` [s,t,a,b]-      ReviewType                   -> reviewTypeName  `conAppsT` [t,b]--stabType :: Stab -> OpticType-stabType (Stab _ o _ _ _ _) = o--computeOpticType :: Type -> [NCon] -> NCon -> Q Stab-computeOpticType t cons con =-  do let cons' = List.delete con cons-     if null (_nconVars con)-         then computePrismType t (view nconCxt con) cons' con-         else computeReviewType t (view nconCxt con) (view nconTypes con)--computeReviewType :: Type -> Cxt -> [Type] -> Q Stab-computeReviewType s' cx tys =-  do let t = s'-     s <- fmap VarT (newName "s")-     a <- fmap VarT (newName "a")-     b <- toNestedPairT (map return tys)-     return (Stab cx ReviewType s t a b)---- Compute the full type-changing Prism type given an outer type,--- list of constructors, and target constructor name. Additionally--- return 'True' if the resulting type is a "simple" prism.-computePrismType :: Type -> Cxt -> [NCon] -> NCon -> Q Stab-computePrismType t cx cons con =-  do let ts      = view nconTypes con-         unbound = setOf typeVars t Set.\\ setOf typeVars cons-     sub <- sequenceA (Map.fromSet (newName . nameBase) unbound)-     b   <- toNestedPairT (map return ts)-     a   <- toNestedPairT (map return (substTypeVars sub ts))-     let s = substTypeVars sub t-     return (Stab cx PrismType s t a b)--computeIsoType :: Type -> [Type] -> TypeQ-computeIsoType t' fields =-  do sub <- sequenceA (Map.fromSet (newName . nameBase) (setOf typeVars t'))-     let t = return                    t'-         s = return (substTypeVars sub t')-         b = toNestedPairT (map return                    fields)-         a = toNestedPairT (map return (substTypeVars sub fields))-         ty | Map.null sub = appsT (conT iso'TypeName) [t,b]-            | otherwise    = appsT (conT isoTypeName) [s,t,a,b]-     quantifyType [] <$> ty---- Construct either a Review or Prism as appropriate-makeConOpticExp :: Stab -> [NCon] -> NCon -> ExpQ-makeConOpticExp stab cons con =-  case stabType stab of-    PrismType  -> makeConPrismExp stab cons con-    ReviewType -> makeConReviewExp con---- Construct an iso declaration-makeConIso :: Type -> NCon -> DecsQ-makeConIso s con =-  do let ty      = computeIsoType s (view nconTypes con)-         defName = prismName (view nconName con)-     sequenceA-       ( [ sigD       defName  ty-         , valD (varP defName) (normalB (makeConIsoExp con)) []-         ] ++-         inlinePragma defName-       )---- Construct prism expression------ prism <<reviewer>> <<remitter>>-makeConPrismExp ::-  Stab ->-  [NCon] {- ^ constructors       -} ->-  NCon   {- ^ target constructor -} ->-  ExpQ-makeConPrismExp stab cons con = appsE [varE prismValName, reviewer, remitter]-  where-  ts = view nconTypes con-  fields  = length ts-  conName = view nconName con-  reviewer                   = makeReviewer       conName fields-  remitter | stabSimple stab = makeSimpleRemitter conName (length cons) fields-           | otherwise       = makeFullRemitter cons conName---- Construct an Iso expression------ iso <<reviewer>> <<remitter>>-makeConIsoExp :: NCon -> ExpQ-makeConIsoExp con = appsE [varE isoValName, remitter, reviewer]-  where-  conName = view nconName con-  fields  = length (view nconTypes con)-  reviewer = makeReviewer    conName fields-  remitter = makeIsoRemitter conName fields---- Construct a Review expression------ unto (\(x,y,z) -> Con x y z)-makeConReviewExp :: NCon -> ExpQ-makeConReviewExp con = appE (varE untoValName) reviewer-  where-  conName = view nconName con-  fields  = length (view nconTypes con)-  reviewer = makeReviewer conName fields----------------------------------------------------------------------------- Prism and Iso component builders----------------------------------------------------------------------------- Construct the review portion of a prism.------ (\(x,y,z) -> Con x y z) :: b -> t-makeReviewer :: Name -> Int -> ExpQ-makeReviewer conName fields =-  do xs <- newNames "x" fields-     lam1E (toNestedPairP (map varP xs))-           (conE conName `appsE1` map varE xs)---- Construct the remit portion of a prism.--- Pattern match only target constructor, no type changing------ (\x -> case s of---          Con x y z -> Right (x,y,z)---          _         -> Left x--- ) :: s -> Either s a-makeSimpleRemitter ::-  Name {- The name of the constructor on which this prism focuses -} ->-  Int  {- The number of constructors the parent data type has     -} ->-  Int  {- The number of fields the constructor has                -} ->-  ExpQ-makeSimpleRemitter conName numCons fields =-  do x  <- newName "x"-     xs <- newNames "y" fields-     let matches =-           [ match (conP conName (map varP xs))-                   (normalB (appE (conE rightDataName) (toNestedPairE (map varE xs))))-                   []-           ] ++-           [ match wildP (normalB (appE (conE leftDataName) (varE x))) []-           | numCons > 1 -- Only generate a catch-all case if there is at least-                         -- one constructor besides the one being focused on.-           ]-     lam1E (varP x) (caseE (varE x) matches)---- Pattern match all constructors to enable type-changing------ (\x -> case s of---          Con x y z -> Right (x,y,z)---          Other_n w   -> Left (Other_n w)--- ) :: s -> Either t a-makeFullRemitter :: [NCon] -> Name -> ExpQ-makeFullRemitter cons target =-  do x <- newName "x"-     lam1E (varP x) (caseE (varE x) (map mkMatch cons))-  where-  mkMatch (NCon conName _ _ n) =-    do xs <- newNames "y" (length n)-       match (conP conName (map varP xs))-             (normalB-               (if conName == target-                  then appE (conE rightDataName) (toNestedPairE (map varE xs))-                  else appE (conE leftDataName) (conE conName `appsE1` map varE xs)))-             []---- Construct the remitter suitable for use in an 'Iso'------ (\(Con x y z) -> (x,y,z)) :: s -> a-makeIsoRemitter :: Name -> Int -> ExpQ-makeIsoRemitter conName fields =-  do xs <- newNames "x" fields-     lam1E (conP conName (map varP xs))-           (toNestedPairE (map varE xs))----------------------------------------------------------------------------- Utilities----------------------------------------------------------------------------- Normalized constructor-data NCon = NCon-  { _nconName :: Name-  , _nconVars :: [Name]-  , _nconCxt  :: Cxt-  , _nconTypes :: [Type]-  }-  deriving (Eq)-instance HasTypeVars NCon where-  typeVarsEx s f (NCon x vars y z) = NCon x vars <$> typeVarsEx s' f y <*> typeVarsEx s' f z-    where s' = List.foldl' (flip Set.insert) s vars--nconName :: Lens' NCon Name-nconName f x = fmap (\y -> x {_nconName = y}) (f (_nconName x))--nconCxt :: Lens' NCon Cxt-nconCxt f x = fmap (\y -> x {_nconCxt = y}) (f (_nconCxt x))--nconTypes :: Lens' NCon [Type]-nconTypes f x = fmap (\y -> x {_nconTypes = y}) (f (_nconTypes x))---- Normalize a single 'Con' to its constructor name and field types.-normalizeCon :: D.ConstructorInfo -> NCon-normalizeCon info = NCon (D.constructorName info)-                         (D.tvName <$> D.constructorVars info)-                         (D.constructorContext info)-                         (D.constructorFields info)---- Compute a prism's name by prefixing an underscore for normal--- constructors and period for operators.-prismName ::-  Name {- type constructor        -} ->-  Name {- prism name              -}-prismName n =-  case nameBase n of-    [] -> error "prismName: empty name base?"-    nb@(x:_) | isUpper x -> mkName (prefix '_' nb)-             | otherwise -> mkName (prefix '.' nb) -- operator-  where-    prefix :: Char -> String -> String-    prefix char str = char:str---- Construct a tuple type given a list of types.-toNestedPairT :: [TypeQ] -> TypeQ-toNestedPairT [] = appsT (tupleT 0) []-toNestedPairT [x] = x-toNestedPairT (x:xs) = appsT (tupleT 2) [x, toNestedPairT xs]---- Construct a tuple value given a list of expressions.-toNestedPairE :: [ExpQ] -> ExpQ-toNestedPairE [] = tupE []-toNestedPairE [x] = x-toNestedPairE (x:xs) = tupE [x, toNestedPairE xs]---- Construct a tuple pattern given a list of patterns.-toNestedPairP :: [PatQ] -> PatQ-toNestedPairP [] = tupP []-toNestedPairP [x] = x-toNestedPairP (x:xs) = tupP [x, toNestedPairP xs]
src/Control/Lens/PartialIso.hs view
@@ -11,8 +11,6 @@ [Invertible syntax descriptions](https://www.informatik.uni-marburg.de/~rendel/unparse/) -} -{-# OPTIONS_GHC -Wno-orphans #-}- module Control.Lens.PartialIso   ( -- * PartialIso     dimapMaybe@@ -55,15 +53,13 @@   ) where  import Control.Lens-import Control.Lens.Internal.NestedPrismTH+import Control.Lens.Grammar.Internal.Orphanage ()+import Control.Lens.Grammar.Internal.NestedPrismTH import Control.Lens.Internal.Profunctor import Control.Lens.Iso import Control.Lens.Prism import Control.Monad-import Data.Functor.Compose import Data.Profunctor-import Data.Profunctor.Monad-import Data.Profunctor.Yoneda import Witherable  {- | The `dimapMaybe` function endows@@ -333,27 +329,3 @@ difoldr pattern   = dimap (Empty,) (fmap snd)   . difoldr1 pattern---- Orphanage ----instance (Profunctor p, Functor f)-  => Functor (WrappedPafb f p a) where fmap = rmap-deriving via Compose (p a) f instance-  (Profunctor p, Functor (p a), Filterable f)-    => Filterable (WrappedPafb f p a)-instance (Profunctor p, Filterable f)-  => Cochoice (WrappedPafb f p) where-    unleft (WrapPafb p) = WrapPafb $-      dimap Left (mapMaybe (either Just (const Nothing))) p-    unright (WrapPafb p) = WrapPafb $-      dimap Right (mapMaybe (either (const Nothing) Just)) p-instance (Profunctor p, Filterable (p a))-  => Filterable (Yoneda p a) where-    catMaybes = proreturn . catMaybes . proextract-instance (Profunctor p, Filterable (p a))-  => Filterable (Coyoneda p a) where-    catMaybes = proreturn . catMaybes . proextract-instance Filterable (Forget r a) where-  catMaybes (Forget f) = Forget f-instance Filterable f => Filterable (Star f a) where-  catMaybes (Star f) = Star (catMaybes . f)
src/Control/Monad/Fail/Try.hs view
@@ -17,25 +17,35 @@   , MonadPlus (..)     -- * Alternative   , Alternative (..)+    -- * Filterable+  , Filterable (..)   ) where  import Control.Applicative+import Control.Lens.Grammar.BackusNaur+import Control.Lens.PartialIso () import Control.Monad+import Data.Bifunctor.Joker+import Text.ParserCombinators.ReadP (ReadP)+import Witherable -{- | `MonadTry` is a failure handling interface,-with `fail` & `try` and redundant alternation operators.+{- | `MonadTry` is a failure handling interface, with `fail` & `try`+and redundant alternation & filtration operators.  prop> empty = mzero prop> (<|>) = mplus+prop> filter = mfilter -When a `MonadTry` is also a-`Control.Lens.Grammar.BackusNaur.BackusNaurForm`,-then the following invariant should hold.+`MonadTry` also supports the `BackusNaurForm` interface+for tracing failures and the following invariant should hold.  prop> fail label = rule label empty  -}-class (MonadFail m, MonadPlus m) => MonadTry m where+class+  ( MonadFail m, MonadPlus m, Filterable m+  , forall x. BackusNaurForm (m x)+  ) => MonadTry m where    {- | A handler for failures.   Used for backtracking state on failure in@@ -44,3 +54,7 @@   try :: m a -> m a   default try :: m a -> m a   try = id++instance MonadTry m => MonadTry (Joker m a) where+  try = Joker . try . runJoker+instance MonadTry ReadP
src/Data/Profunctor/Distributor.hs view
@@ -276,3 +276,9 @@   alternate (Right p) = proreturn (alternate (Right (proextract p)))   someP = proreturn . someP . proextract   optionP def = proreturn . optionP def . proextract+instance Alternative f => Alternator (Joker f) where+  alternate (Left (Joker x)) = Joker (Left <$> x)+  alternate (Right (Joker y)) = Joker (Right <$> y)+  someP (Joker x) = Joker (some x)+  optionP def (Joker x) =+    Joker (x <|> withPrism def (\f _ -> pure (f ())))
src/Data/Profunctor/Filtrator.hs view
@@ -19,6 +19,7 @@ import Control.Lens.PartialIso import Control.Lens.Internal.Profunctor import Control.Monad+import Data.Bifunctor.Joker import Data.Profunctor import Data.Profunctor.Distributor import Data.Profunctor.Monad@@ -38,8 +39,8 @@   => Filtrator p where      {- |-    prop> unleft = fst . filtrate-    prop> unright = snd . filtrate+    prop> unleft = fst . filtrate = lmap Left . mapMaybe (either Just (const Nothing))+    prop> unright = snd . filtrate = lmap Right . mapMaybe (either (const Nothing) Just)      `filtrate` is a distant relative to `Data.Either.partitionEithers`.     `filtrate` can be given a default value for `Monadic`@@ -99,4 +100,9 @@   filtrate (PartialExchange f g) =     ( PartialExchange (f . Left) (either Just (pure Nothing) <=< g)     , PartialExchange (f . Right) (either (pure Nothing) Just <=< g)+    )+instance Filterable f => Filtrator (Joker f) where+  filtrate (Joker x) =+    ( Joker (mapMaybe (either Just (const Nothing)) x)+    , Joker (mapMaybe (either (const Nothing) Just) x)     )
src/Data/Profunctor/Grammar.hs view
@@ -40,7 +40,6 @@ import Data.Void import Prelude hiding (id, (.)) import GHC.Exts-import Witherable  -- | `Printor` is a simple printer `Profunctor`. newtype Printor s f a b = Printor {runPrintor :: a -> f (b, s -> s)}@@ -180,7 +179,8 @@ instance BackusNaurForm (Parsor s m a b) instance (Alternative m, Monad m) => MonadFail (Parsor s m a) where   fail _ = empty-instance (Alternative m, Monad m) => MonadTry (Parsor s m a)+instance (Alternative m, Monad m, Filterable m)+  => MonadTry (Parsor s m a) instance AsEmpty s => Matching s (Parsor s [] a b) where   word =~ p = case     [ () | (_, remaining) <- runParsor p Nothing word@@ -289,7 +289,8 @@ instance BackusNaurForm (Printor s m a b) instance (Alternative m, Monad m) => MonadFail (Printor s m a) where   fail _ = empty-instance (Alternative m, Monad m) => MonadTry (Printor s m a)+instance (Alternative m, Monad m, Filterable m)+  => MonadTry (Printor s m a)  -- Grammor instances instance Functor (Grammor k a) where fmap _ = coerce
src/Data/Profunctor/Grammar/Parsector.hs view
@@ -1,6 +1,6 @@ {-| Module      : Data.Profunctor.Grammar.Parsector-Description : grammar distributor with errors+Description : grammar distributor with failures Copyright   : (C) 2026 - Eitan Chatav License     : BSD-style (see the file LICENSE) Maintainer  : Eitan Chatav <eitan.chatav@gmail.com>@@ -18,7 +18,7 @@   , parsecP   , unparsecP   , ParsecState (..)-  , ParsecError (..)+  , ParsecFailure (..)   ) where  import Control.Applicative@@ -41,10 +41,9 @@ import Data.Tree import GHC.Exts import Prelude hiding (id, (.))-import Witherable  {- | `Parsector` is an invertible @LL(1)@ parser which is intended-to provide detailed error information, based on [Parsec]+to provide detailed failure information, based on [Parsec] (https://www.microsoft.com/en-us/research/wp-content/uploads/2016/02/parsec-paper-letter.pdf). -} newtype Parsector s a b = Parsector@@ -91,11 +90,11 @@   , parsecOffset :: !Word     -- ^ Number of tokens consumed from the start of the stream.   , parsecStream :: s -- ^ stream-  , parsecError  :: ParsecError s-    {- ^ `ParsecError` channel.+  , parsecFailure  :: ParsecFailure s+    {- ^ `ParsecFailure` channel.      * If `parsecResult` is `Nothing`, this is the hard failure.-    * If `parsecResult` is `Just`, this is deferred error/hint info+    * If `parsecResult` is `Just`, this is deferred failure/hint info       from empty-failing alternatives at the current position.      `<|>` and `>>=` propagate and merge this field to preserve@@ -106,22 +105,22 @@     As input, `Nothing` means parse mode and     `Just` means print mode with an input syntax value. -    As output `Nothing` means failure (inspect `parsecError`) and+    As output `Nothing` means failure (inspect `parsecFailure`) and     `Just` means success with an output syntax value.     -}   } -{- | `ParsecError` is the error payload produced by `Parsector`,-stored in `parsecError`.-`ParsecError` is a `Monoid` and `Parsector` merges errors/hints+{- | `ParsecFailure` is the failure payload produced by `Parsector`,+stored in `parsecFailure`.+`ParsecFailure` is a `Monoid` and `Parsector` merges failures/hints when control flow reaches the same offset without commitment. -}-data ParsecError s = ParsecError+data ParsecFailure s = ParsecFailure   { parsecExpect :: TokenClass (Item s)     {- ^ Class of expected token `Item`s at the `parsecOffset`.     `tokenClass`es and `Tokenized` combinators specify expectations.     Under `<>`, expectations are combined with disjunction `>||<`.-    In case of a parse error, contrast with the actual `parsecStream`,+    In case of a parse failure, contrast with the actual `parsecStream`,     which is either unexpectedly empty or begins with an unexpected token.     -}   , parsecLabels :: [Tree String]@@ -133,21 +132,21 @@     -}   } --- ParsecError instances+-- ParsecFailure instances deriving stock instance   ( Categorized (Item s)   , Show (Item s), Show (Categorize (Item s))-  ) => Show (ParsecError s)+  ) => Show (ParsecFailure s) deriving stock instance   ( Categorized (Item s)   , Read (Item s), Read (Categorize (Item s))-  ) => Read (ParsecError s)-deriving stock instance Categorized (Item s) => Eq (ParsecError s)-deriving stock instance Categorized (Item s) => Ord (ParsecError s)-instance Categorized (Item s) => Semigroup (ParsecError s) where-  ParsecError e1 l1 <> ParsecError e2 l2 = ParsecError (e1 >||< e2) (l1 ++ l2)-instance Categorized (Item s) => Monoid (ParsecError s) where-  mempty = ParsecError falseB []+  ) => Read (ParsecFailure s)+deriving stock instance Categorized (Item s) => Eq (ParsecFailure s)+deriving stock instance Categorized (Item s) => Ord (ParsecFailure s)+instance Categorized (Item s) => Semigroup (ParsecFailure s) where+  ParsecFailure e1 l1 <> ParsecFailure e2 l2 = ParsecFailure (e1 >||< e2) (l1 ++ l2)+instance Categorized (Item s) => Monoid (ParsecFailure s) where+  mempty = ParsecFailure falseB []  -- ParsecState instances deriving stock instance Functor (ParsecState s)@@ -194,13 +193,13 @@         offset = parsecOffset query         replyOk tok str = query           { parsecLooked = True-          , parsecError  = mempty+          , parsecFailure  = mempty           , parsecStream = str           , parsecOffset = offset + 1           , parsecResult = Just tok           }         replyErr = query-          { parsecError  = ParsecError test []+          { parsecFailure  = ParsecFailure test []           , parsecResult = Nothing }       in         callback $ case mode of@@ -221,9 +220,9 @@     flip (runParsector p) query $ \reply -> callback $       case parsecResult reply of         Nothing -> reply-          { parsecError =-              let ParsecError expect labels = parsecError reply-              in ParsecError expect [Node name labels]+          { parsecFailure =+              let ParsecFailure expect labels = parsecFailure reply+              in ParsecFailure expect [Node name labels]           }         Just _ -> reply   ruleRec name = rule name . fix@@ -246,10 +245,10 @@         Nothing -> callback reply { parsecResult = Nothing }         Just b ->           let-            hintP  = parsecError reply+            hintP  = parsecFailure reply             fQuery = reply               { parsecLooked = False-              , parsecError  = mempty+              , parsecFailure  = mempty               , parsecResult = parsecResult query               }           in@@ -258,12 +257,12 @@                 then fReply                 else fReply                   { parsecLooked = parsecLooked reply-                  , parsecError  = hintP <> parsecError fReply+                  , parsecFailure  = hintP <> parsecFailure fReply                   } instance Categorized (Item s) => Alternative (Parsector s a) where   -- | Always fails without consuming input; expects nothing.   empty = Parsector $ \callback query ->-    callback query { parsecError = mempty, parsecResult = Nothing }+    callback query { parsecFailure = mempty, parsecResult = Nothing }   p <|> q = Parsector $ \callback query ->     flip (runParsector p) query $ \replyP -> callback $       case parsecResult replyP of@@ -273,15 +272,15 @@         Nothing | parsecLooked replyP -> replyP         -- if p failed without consuming, try q         Nothing ->-          let errP = parsecError replyP+          let errP = parsecFailure replyP           in flip (runParsector q) query $ \replyQ ->           case (parsecLooked replyQ, parsecResult replyQ) of             -- q consumed (ok or err): propagate as-is, drop errP             (True, _)         -> replyQ             -- q empty ok: carry errP forward as hint for downstream-            (False, Just _)   -> replyQ { parsecError = errP <> parsecError replyQ }-            -- both empty fail: merge errors-            (False, Nothing)  -> replyP { parsecError = errP <> parsecError replyQ }+            (False, Just _)   -> replyQ { parsecFailure = errP <> parsecFailure replyQ }+            -- both empty fail: merge failures+            (False, Nothing)  -> replyP { parsecFailure = errP <> parsecFailure replyQ } instance Categorized (Item s) => MonadPlus (Parsector s a) instance Categorized (Item s) => MonadFail (Parsector s a) where   fail msg = rule msg empty@@ -295,7 +294,7 @@       case parsecResult reply of         Nothing -> query           { parsecLooked = False-          , parsecError  = parsecError reply+          , parsecFailure  = parsecFailure reply           , parsecResult = Nothing           }         Just _ -> reply@@ -348,7 +347,7 @@             Just (Left a)   -> Just a             Just (Right _)  -> Nothing         }-      replyErr = query { parsecError = mempty, parsecResult = Nothing }+      replyErr = query { parsecFailure = mempty, parsecResult = Nothing }     in       case (parsecResult query, parsecResult replyOk) of         (Just _, Nothing) -> replyErr@@ -363,7 +362,7 @@             Just (Left _)   -> Nothing             Just (Right b)  -> Just b         }-      replyErr = query { parsecError = mempty, parsecResult = Nothing }+      replyErr = query { parsecFailure = mempty, parsecResult = Nothing }     in       case (parsecResult query, parsecResult replyOk) of         (Just _, Nothing) -> replyErr@@ -382,18 +381,18 @@     ( Parsector $ \callback query ->         flip (runParsector p) (Left <$> query) $ \reply ->           callback reply-          { parsecError = case parsecResult reply of+          { parsecFailure = case parsecResult reply of             Just (Right _) -> mempty-            _ -> parsecError reply+            _ -> parsecFailure reply           , parsecResult =             parsecResult reply >>= either Just (const Nothing)           }     , Parsector $ \callback query ->         flip (runParsector p) (Right <$> query) $ \reply ->           callback reply-          { parsecError = case parsecResult reply of+          { parsecFailure = case parsecResult reply of             Just (Left _) -> mempty-            _ -> parsecError reply+            _ -> parsecFailure reply           , parsecResult =             parsecResult reply >>= either (const Nothing) Just           }
src/Data/Profunctor/Monoidal.hs view
@@ -20,26 +20,10 @@   , meander, eotFunList   ) where -import Control.Applicative hiding (WrappedArrow)-import Control.Applicative qualified as Ap (WrappedArrow)-import Control.Arrow-import Control.Lens hiding (chosen)+import Control.Lens import Control.Lens.Internal.Context-import Control.Lens.Internal.Prism-import Control.Lens.Internal.Profunctor import Control.Lens.PartialIso-import Data.Bifunctor.Clown-import Data.Bifunctor.Joker-import Data.Bifunctor.Product import Data.Distributive-import Data.Functor.Compose-import Data.Functor.Contravariant.Divisible-import Data.Profunctor hiding (WrappedArrow)-import Data.Profunctor qualified as Pro (WrappedArrow)-import Data.Profunctor.Cayley-import Data.Profunctor.Composition-import Data.Profunctor.Monad-import Data.Profunctor.Yoneda import GHC.IsList  -- Monoidal --@@ -161,11 +145,11 @@ replicateP n _ | n <= 0 = asEmpty replicateP n a = a >:< replicateP (n-1) a -{- | For any `Monoidal`, `Choice` & `Strong` `Profunctor`,+{- | For any `Monoidal`, `Choice` & `Data.Profunctor.Strong` `Profunctor`, `meander` is invertible and gives a default implementation for the `Data.Profunctor.Traversing.wander` method of `Data.Profunctor.Traversing.Traversing`,-though `Strong` is not needed for its definition.+though `Data.Profunctor.Strong` is not needed for its definition.  See Pickering, Gibbons & Wu, [Profunctor Optics - Modular Data Accessors](https://arxiv.org/abs/1703.10857)@@ -217,72 +201,3 @@     MoreFun a h -> \l ->       MoreFun a (flip <$> h <*> fromFun l) instance Sellable (->) FunList where sell b = MoreFun b (pure id)---- Orphanage ----instance Monoid r => Applicative (Forget r a) where-  pure _ = Forget mempty-  Forget f <*> Forget g = Forget (f <> g)-instance Decidable f => Applicative (Clown f a) where-  pure _ = Clown conquer-  Clown x <*> Clown y = Clown (divide (id &&& id) x y)-deriving newtype instance Applicative f => Applicative (Joker f a)-deriving via Compose (p a) f instance-  (Profunctor p, Applicative (p a), Applicative f)-    => Applicative (WrappedPafb f p a)-deriving via Compose (p a) f instance-  (Profunctor p, Alternative (p a), Applicative f)-    => Alternative (WrappedPafb f p a)-instance (Closed p, Distributive f)-  => Closed (WrappedPafb f p) where-    closed (WrapPafb p) = WrapPafb (rmap distribute (closed p))-deriving via (Ap.WrappedArrow p a) instance Arrow p-  => Functor (Pro.WrappedArrow p a)-deriving via (Ap.WrappedArrow p a) instance Arrow p-  => Applicative (Pro.WrappedArrow p a)-deriving via (Pro.WrappedArrow p) instance Arrow p-  => Profunctor (Ap.WrappedArrow p)-instance (Monoidal p, Applicative (q a))-  => Applicative (Procompose p q a) where-    pure b = Procompose (pure b) (pure b)-    Procompose wb aw <*> Procompose vb av = Procompose-      (dimap2 fst snd ($) wb vb)-      (liftA2 (,) aw av)-instance (Monoidal p, Monoidal q)-  => Applicative (Product p q a) where-    pure b = Pair (pure b) (pure b)-    Pair x0 y0 <*> Pair x1 y1 = Pair (x0 <*> x1) (y0 <*> y1)-instance (Functor f, Functor (p a)) => Functor (Cayley f p a) where-  fmap f (Cayley x) = Cayley (fmap (fmap f) x)-instance (Applicative f, Applicative (p a)) => Applicative (Cayley f p a) where-  pure b = Cayley (pure (pure b))-  Cayley x <*> Cayley y = Cayley ((<*>) <$> x <*> y)-instance (Profunctor p, Applicative (p a))-  => Applicative (Yoneda p a) where-    pure = proreturn . pure-    ab <*> cd = proreturn (proextract ab <*> proextract cd)-instance (Profunctor p, Applicative (p a))-  => Applicative (Coyoneda p a) where-    pure = proreturn . pure-    ab <*> cd = proreturn (proextract ab <*> proextract cd)-instance (Profunctor p, Alternative (p a))-  => Alternative (Yoneda p a) where-    empty = proreturn empty-    ab <|> cd = proreturn (proextract ab <|> proextract cd)-    many = proreturn . many . proextract-instance (Profunctor p, Alternative (p a))-  => Alternative (Coyoneda p a) where-    empty = proreturn empty-    ab <|> cd = proreturn (proextract ab <|> proextract cd)-    many = proreturn . many . proextract-instance Applicative (Market a b s) where-  pure t = Market (pure t) (pure (Left t))-  Market f0 g0 <*> Market f1 g1 = Market-    (\b -> f0 b (f1 b))-    (\s ->-      case g0 s of-        Left bt -> case g1 s of-          Left b -> Left (bt b)-          Right a -> Right a-        Right a -> Right a-    )
test/Main.hs view
@@ -4,12 +4,14 @@ import Control.Lens.Grammar import Control.Monad (when) import Data.IORef+import Data.Function (fix) import Data.List (genericLength) import Data.Maybe (isJust) import Data.Profunctor.Types (Star (..)) import System.Environment (lookupEnv) import Test.DocTest import Test.Hspec+import qualified Text.Megaparsec as M  import Examples.Arithmetic import Examples.Chain@@ -138,13 +140,43 @@       let actualSyntax = parsecG grammar expectedString       let expectedLength = genericLength expectedString       let actualLooked = parsecLooked actualSyntax-      let actualError  = parsecError  actualSyntax+      let actualFailure  = parsecFailure  actualSyntax       actualSyntax `shouldBe`-        (ParsecState actualLooked expectedLength "" actualError (Just expectedSyntax))+        (ParsecState actualLooked expectedLength "" actualFailure (Just expectedSyntax))     it ("should unparsecG to " <> expectedString <> " correctly") $ do       let actualString = unparsecG grammar expectedSyntax ""       let expectedLength = genericLength expectedString       let actualLooked = parsecLooked actualString-      let actualError  = parsecError  actualString+      let actualFailure  = parsecFailure  actualString       actualString `shouldBe`-        (ParsecState actualLooked expectedLength expectedString actualError (Just expectedSyntax))+        (ParsecState actualLooked expectedLength expectedString actualFailure (Just expectedSyntax))+    it ("should parse with megaparsec to " <> expectedString <> " correctly") $ do+      let megaparsec = unwrapMega (monadG grammar)+      let actualSyntax = M.parse megaparsec "<megaparsec>" expectedString+      actualSyntax `shouldBe` Right expectedSyntax++newtype WrapMega a = WrapMega {unwrapMega :: M.Parsec String String a}+  deriving newtype+    ( Functor, Applicative, Alternative+    , Monad, MonadPlus, MonadFail+    )+instance TerminalSymbol Char (WrapMega ()) where+  terminal str = WrapMega (M.chunk str *> pure ())+instance TokenAlgebra Char (WrapMega Char) where+  tokenClass exam = WrapMega $ M.label (show exam) (M.satisfy (tokenClass exam))+instance Tokenized Char (WrapMega Char) where+  anyToken = WrapMega M.anySingle+  token = WrapMega . M.single+  oneOf = WrapMega . M.oneOf+  notOneOf = WrapMega . M.noneOf+  asIn cat = WrapMega $ M.label ("in category " ++ show cat)+    (M.satisfy (tokenClass (asIn cat)))+  notAsIn cat = WrapMega $ M.label ("not in category " ++ show cat)+    (M.satisfy (tokenClass (notAsIn cat)))+instance BackusNaurForm (WrapMega a) where+  rule lbl (WrapMega p) = WrapMega (M.label lbl p)+  ruleRec lbl = rule lbl . fix+instance Filterable WrapMega where+  catMaybes m = m >>= maybe (fail "unrestricted filtration") pure+instance MonadTry WrapMega where+  try (WrapMega p) = WrapMega (M.try p)