{-# LANGUAGE ExistentialQuantification #-}-- |-- Module : Control.Applicative.Permutations-- Copyright : © 2017–present Alex Washburn-- License : BSD 3 clause---- Maintainer : Mark Karpov <markkarpov92@gmail.com>-- Stability : experimental-- Portability : portable---- This module is a generalization of the package @parsec-permutation@-- authored by Samuel Hoffstaetter:---- https://hackage.haskell.org/package/parsec-permutation---- This module also takes inspiration from the algorithm is described in:-- /Parsing Permutation Phrases/, by Arthur Baars, Andres Löh and Doaitse-- Swierstra. Published as a functional pearl at the Haskell Workshop 2001:---- https://www.cs.ox.ac.uk/jeremy.gibbons/wg21/meeting56/loeh-paper.pdf---- From these two works we derive a flexible and general method for parsing-- permutations over an 'Applicative' structure. Quite useful in conjunction-- with \"Free\" constructions of 'Applicative's, 'Monad's, etc.---- Other permutation parsing libraries tend towards using special \"almost-- applicative\" combinators for construction which denies the library user-- the ability to lift and unlift permutation parsing into any 'Applicative'-- computational context. We redefine these combinators as convenience-- operators here alongside the equivalent 'Applicative' instance.---- For example, suppose we want to parse a permutation of: an optional-- string of @a@'s, the character @b@ and an optional @c@. Using a standard-- parsing library combinator @char@ (e.g. 'Text.ParserCombinators.ReadP.ReadP')-- this can be described using the 'Applicative' instance by:---- > test = runPermutation $-- > (,,) <$> toPermutationWithDefault "" (some (char 'a'))-- > <*> toPermutation (char 'b')-- > <*> toPermutationWithDefault '_' (char 'c')---- @since 0.2.0moduleControl.Applicative.Permutations(-- ** Permutation typePermutation ,-- ** Permutation evaluatorsrunPermutation ,intercalateEffect ,-- ** Permutation constructorstoPermutation ,toPermutationWithDefault ,)whereimportControl.ApplicativeimportData.Function((&))-- | An 'Applicative' wrapper-type for constructing permutation parsers.dataPermutation m a =P !(Maybea )[Branch m a ]dataBranch m a =forallz .Branch (Permutation m (z ->a ))(m z )instanceFunctorm =>Functor(Permutation m )wherefmap :: (a -> b) -> Permutation m a -> Permutation m b
fmapa -> b
f (P Maybe a
v [Branch m a]
bs )=Maybe b -> [Branch m b] -> Permutation m b
forall (m :: * -> *) a. Maybe a -> [Branch m a] -> Permutation m a
P (a -> b
f (a -> b) -> Maybe a -> Maybe b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$>Maybe a
v )((a -> b) -> Branch m a -> Branch m b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmapa -> b
f (Branch m a -> Branch m b) -> [Branch m a] -> [Branch m b]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$>[Branch m a]
bs )instanceFunctorp =>Functor(Branch p )wherefmap :: (a -> b) -> Branch p a -> Branch p b
fmapa -> b
f (Branch Permutation p (z -> a)
perm p z
p )=Permutation p (z -> b) -> p z -> Branch p b
forall (m :: * -> *) a z.
Permutation m (z -> a) -> m z -> Branch m a
Branch (((z -> a) -> z -> b)
-> Permutation p (z -> a) -> Permutation p (z -> b)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap(a -> b
f (a -> b) -> (z -> a) -> z -> b
forall b c a. (b -> c) -> (a -> b) -> a -> c
.)Permutation p (z -> a)
perm )p z
p instanceFunctorm =>Applicative(Permutation m )wherepure :: a -> Permutation m a
purea
value =Maybe a -> [Branch m a] -> Permutation m a
forall (m :: * -> *) a. Maybe a -> [Branch m a] -> Permutation m a
P (a -> Maybe a
forall a. a -> Maybe a
Justa
value )[Branch m a]
forall (f :: * -> *) a. Alternative f => f a
emptylhs :: Permutation m (a -> b)
lhs @(P Maybe (a -> b)
f [Branch m (a -> b)]
v )<*> :: Permutation m (a -> b) -> Permutation m a -> Permutation m b
<*>rhs :: Permutation m a
rhs @(P Maybe a
g [Branch m a]
w )=Maybe b -> [Branch m b] -> Permutation m b
forall (m :: * -> *) a. Maybe a -> [Branch m a] -> Permutation m a
P (Maybe (a -> b)
f Maybe (a -> b) -> Maybe a -> Maybe b
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*>Maybe a
g )([Branch m b] -> Permutation m b)
-> [Branch m b] -> Permutation m b
forall a b. (a -> b) -> a -> b
$(Branch m (a -> b) -> Branch m b
forall a. Branch m (a -> a) -> Branch m a
ins2 (Branch m (a -> b) -> Branch m b)
-> [Branch m (a -> b)] -> [Branch m b]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$>[Branch m (a -> b)]
v )[Branch m b] -> [Branch m b] -> [Branch m b]
forall a. Semigroup a => a -> a -> a
<>(Branch m a -> Branch m b
ins1 (Branch m a -> Branch m b) -> [Branch m a] -> [Branch m b]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$>[Branch m a]
w )whereins1 :: Branch m a -> Branch m b
ins1 (Branch Permutation m (z -> a)
perm m z
p )=Permutation m (z -> b) -> m z -> Branch m b
forall (m :: * -> *) a z.
Permutation m (z -> a) -> m z -> Branch m a
Branch ((a -> b) -> (z -> a) -> z -> b
forall b c a. (b -> c) -> (a -> b) -> a -> c
(.)((a -> b) -> (z -> a) -> z -> b)
-> Permutation m (a -> b) -> Permutation m ((z -> a) -> z -> b)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$>Permutation m (a -> b)
lhs Permutation m ((z -> a) -> z -> b)
-> Permutation m (z -> a) -> Permutation m (z -> b)
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*>Permutation m (z -> a)
perm )m z
p ins2 :: Branch m (a -> a) -> Branch m a
ins2 (Branch Permutation m (z -> a -> a)
perm m z
p )=Permutation m (z -> a) -> m z -> Branch m a
forall (m :: * -> *) a z.
Permutation m (z -> a) -> m z -> Branch m a
Branch ((z -> a -> a) -> a -> z -> a
forall a b c. (a -> b -> c) -> b -> a -> c
flip((z -> a -> a) -> a -> z -> a)
-> Permutation m (z -> a -> a) -> Permutation m (a -> z -> a)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$>Permutation m (z -> a -> a)
perm Permutation m (a -> z -> a)
-> Permutation m a -> Permutation m (z -> a)
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*>Permutation m a
rhs )m z
p liftA2 :: (a -> b -> c)
-> Permutation m a -> Permutation m b -> Permutation m c
liftA2a -> b -> c
f lhs :: Permutation m a
lhs @(P Maybe a
x [Branch m a]
v )rhs :: Permutation m b
rhs @(P Maybe b
y [Branch m b]
w )=Maybe c -> [Branch m c] -> Permutation m c
forall (m :: * -> *) a. Maybe a -> [Branch m a] -> Permutation m a
P ((a -> b -> c) -> Maybe a -> Maybe b -> Maybe c
forall (f :: * -> *) a b c.
Applicative f =>
(a -> b -> c) -> f a -> f b -> f c
liftA2a -> b -> c
f Maybe a
x Maybe b
y )([Branch m c] -> Permutation m c)
-> [Branch m c] -> Permutation m c
forall a b. (a -> b) -> a -> b
$(Branch m a -> Branch m c
ins2 (Branch m a -> Branch m c) -> [Branch m a] -> [Branch m c]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$>[Branch m a]
v )[Branch m c] -> [Branch m c] -> [Branch m c]
forall a. Semigroup a => a -> a -> a
<>(Branch m b -> Branch m c
ins1 (Branch m b -> Branch m c) -> [Branch m b] -> [Branch m c]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$>[Branch m b]
w )whereins1 :: Branch m b -> Branch m c
ins1 (Branch Permutation m (z -> b)
perm m z
p )=Permutation m (z -> c) -> m z -> Branch m c
forall (m :: * -> *) a z.
Permutation m (z -> a) -> m z -> Branch m a
Branch ((a -> (z -> b) -> z -> c)
-> Permutation m a
-> Permutation m (z -> b)
-> Permutation m (z -> c)
forall (f :: * -> *) a b c.
Applicative f =>
(a -> b -> c) -> f a -> f b -> f c
liftA2((b -> c) -> (z -> b) -> z -> c
forall b c a. (b -> c) -> (a -> b) -> a -> c
(.)((b -> c) -> (z -> b) -> z -> c)
-> (a -> b -> c) -> a -> (z -> b) -> z -> c
forall b c a. (b -> c) -> (a -> b) -> a -> c
.a -> b -> c
f )Permutation m a
lhs Permutation m (z -> b)
perm )m z
p ins2 :: Branch m a -> Branch m c
ins2 (Branch Permutation m (z -> a)
perm m z
p )=Permutation m (z -> c) -> m z -> Branch m c
forall (m :: * -> *) a z.
Permutation m (z -> a) -> m z -> Branch m a
Branch ((b -> (z -> a) -> z -> c)
-> Permutation m b
-> Permutation m (z -> a)
-> Permutation m (z -> c)
forall (f :: * -> *) a b c.
Applicative f =>
(a -> b -> c) -> f a -> f b -> f c
liftA2(\b
b z -> a
g z
z ->a -> b -> c
f (z -> a
g z
z )b
b )Permutation m b
rhs Permutation m (z -> a)
perm )m z
p -- | \"Unlifts\" a permutation parser into a parser to be evaluated.runPermutation ::Alternativem =>-- | Permutation specificationPermutation m a ->-- | Resulting base monad capable of handling the permutationm a runPermutation :: Permutation m a -> m a
runPermutation =(Branch m a -> m a) -> Permutation m a -> m a
forall (m :: * -> *) a.
Alternative m =>
(Branch m a -> m a) -> Permutation m a -> m a
foldAlt Branch m a -> m a
forall (m :: * -> *) a. Alternative m => Branch m a -> m a
f where-- INCORRECT = runPerms t <*> pf :: Branch m a -> m a
f (Branch Permutation m (z -> a)
t m z
p )=z -> (z -> a) -> a
forall a b. a -> (a -> b) -> b
(&)(z -> (z -> a) -> a) -> m z -> m ((z -> a) -> a)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$>m z
p m ((z -> a) -> a) -> m (z -> a) -> m a
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*>Permutation m (z -> a) -> m (z -> a)
forall (m :: * -> *) a. Alternative m => Permutation m a -> m a
runPermutation Permutation m (z -> a)
t -- | \"Unlifts\" a permutation parser into a parser to be evaluated with an-- intercalated effect. Useful for separators between permutation elements.---- For example, suppose that similar to above we want to parse a permutation-- of: an optional string of @a@'s, the character @b@ and an optional @c@.-- /However/, we also want each element of the permutation to be separated-- by a colon. Using a standard parsing library combinator @char@, this can-- be described using the 'Applicative' instance by:---- > test = intercalateEffect (char ':') $-- > (,,) <$> toPermutationWithDefault "" (some (char 'a'))-- > <*> toPermutation (char 'b')-- > <*> toPermutationWithDefault '_' (char 'c')---- This will accept strings such as: \"a:b:c\", \"b:c:a\", \"b:aa\", \"b\",-- etc.---- Note that the effect is intercalated /between/ permutation components and-- that:---- * There is never an effect parsed preceeding the first component of-- the permutation.-- * There is never an effect parsed following the last component of the-- permutation.-- * No effects are intercalated between missing components with a-- default value.-- * If an effect is encountered after a component, another component must-- immediately follow the effect.intercalateEffect ::Alternativem =>-- | Effect to be intercalated between permutation componentsm b ->-- | Permutation specificationPermutation m a ->-- | Resulting base applicative capable of handling the permutationm a intercalateEffect :: m b -> Permutation m a -> m a
intercalateEffect m b
effect =(Branch m a -> m a) -> Permutation m a -> m a
forall (m :: * -> *) a.
Alternative m =>
(Branch m a -> m a) -> Permutation m a -> m a
foldAlt (m b -> Branch m a -> m a
forall (m :: * -> *) b a. Alternative m => m b -> Branch m a -> m a
runBranchEff m b
effect )whererunPermEff ::Alternativem =>m b ->Permutation m a ->m a runPermEff :: m b -> Permutation m a -> m a
runPermEff m b
eff (P Maybe a
v [Branch m a]
bs )=m b
eff m b -> m a -> m a
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f b
*>(Branch m a -> m a -> m a) -> m a -> [Branch m a] -> m a
forall (t :: * -> *) a b.
Foldable t =>
(a -> b -> b) -> b -> t a -> b
foldr(m a -> m a -> m a
forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
(<|>)(m a -> m a -> m a)
-> (Branch m a -> m a) -> Branch m a -> m a -> m a
forall b c a. (b -> c) -> (a -> b) -> a -> c
.m b -> Branch m a -> m a
forall (m :: * -> *) b a. Alternative m => m b -> Branch m a -> m a
runBranchEff m b
eff )m a
forall (f :: * -> *) a. Alternative f => f a
empty[Branch m a]
bs m a -> m a -> m a
forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|>m a -> (a -> m a) -> Maybe a -> m a
forall b a. b -> (a -> b) -> Maybe a -> b
maybem a
forall (f :: * -> *) a. Alternative f => f a
emptya -> m a
forall (f :: * -> *) a. Applicative f => a -> f a
pureMaybe a
v runBranchEff ::Alternativem =>m b ->Branch m a ->m a runBranchEff :: m b -> Branch m a -> m a
runBranchEff m b
eff (Branch Permutation m (z -> a)
t m z
p )=z -> (z -> a) -> a
forall a b. a -> (a -> b) -> b
(&)(z -> (z -> a) -> a) -> m z -> m ((z -> a) -> a)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$>m z
p m ((z -> a) -> a) -> m (z -> a) -> m a
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*>m b -> Permutation m (z -> a) -> m (z -> a)
forall (m :: * -> *) b a.
Alternative m =>
m b -> Permutation m a -> m a
runPermEff m b
eff Permutation m (z -> a)
t -- | \"Lifts\" a parser to a permutation parser.toPermutation ::Alternativem =>-- | Permutation componentm a ->Permutation m a toPermutation :: m a -> Permutation m a
toPermutation =Maybe a -> [Branch m a] -> Permutation m a
forall (m :: * -> *) a. Maybe a -> [Branch m a] -> Permutation m a
P Maybe a
forall a. Maybe a
Nothing([Branch m a] -> Permutation m a)
-> (m a -> [Branch m a]) -> m a -> Permutation m a
forall b c a. (b -> c) -> (a -> b) -> a -> c
.Branch m a -> [Branch m a]
forall (f :: * -> *) a. Applicative f => a -> f a
pure(Branch m a -> [Branch m a])
-> (m a -> Branch m a) -> m a -> [Branch m a]
forall b c a. (b -> c) -> (a -> b) -> a -> c
.m a -> Branch m a
forall (m :: * -> *) a. Functor m => m a -> Branch m a
branch -- | \"Lifts\" a parser with a default value to a permutation parser.---- If no permutation containing the supplied parser can be parsed from the input,-- then the supplied default value is returned in lieu of a parse result.toPermutationWithDefault ::Alternativem =>-- | Default Valuea ->-- | Permutation componentm a ->Permutation m a toPermutationWithDefault :: a -> m a -> Permutation m a
toPermutationWithDefault a
v =Maybe a -> [Branch m a] -> Permutation m a
forall (m :: * -> *) a. Maybe a -> [Branch m a] -> Permutation m a
P (a -> Maybe a
forall a. a -> Maybe a
Justa
v )([Branch m a] -> Permutation m a)
-> (m a -> [Branch m a]) -> m a -> Permutation m a
forall b c a. (b -> c) -> (a -> b) -> a -> c
.Branch m a -> [Branch m a]
forall (f :: * -> *) a. Applicative f => a -> f a
pure(Branch m a -> [Branch m a])
-> (m a -> Branch m a) -> m a -> [Branch m a]
forall b c a. (b -> c) -> (a -> b) -> a -> c
.m a -> Branch m a
forall (m :: * -> *) a. Functor m => m a -> Branch m a
branch branch ::Functorm =>m a ->Branch m a branch :: m a -> Branch m a
branch =Permutation m (a -> a) -> m a -> Branch m a
forall (m :: * -> *) a z.
Permutation m (z -> a) -> m z -> Branch m a
Branch (Permutation m (a -> a) -> m a -> Branch m a)
-> Permutation m (a -> a) -> m a -> Branch m a
forall a b. (a -> b) -> a -> b
$(a -> a) -> Permutation m (a -> a)
forall (f :: * -> *) a. Applicative f => a -> f a
purea -> a
forall a. a -> a
idfoldAlt ::Alternativem =>(Branch m a ->m a )->Permutation m a ->m a foldAlt :: (Branch m a -> m a) -> Permutation m a -> m a
foldAlt Branch m a -> m a
f (P Maybe a
v [Branch m a]
bs )=(Branch m a -> m a -> m a) -> m a -> [Branch m a] -> m a
forall (t :: * -> *) a b.
Foldable t =>
(a -> b -> b) -> b -> t a -> b
foldr(m a -> m a -> m a
forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
(<|>)(m a -> m a -> m a)
-> (Branch m a -> m a) -> Branch m a -> m a -> m a
forall b c a. (b -> c) -> (a -> b) -> a -> c
.Branch m a -> m a
f )(m a -> (a -> m a) -> Maybe a -> m a
forall b a. b -> (a -> b) -> Maybe a -> b
maybem a
forall (f :: * -> *) a. Alternative f => f a
emptya -> m a
forall (f :: * -> *) a. Applicative f => a -> f a
pureMaybe a
v )[Branch m a]
bs 

AltStyle によって変換されたページ (->オリジナル) /