{-# LANGUAGE ExistentialQuantification #-}
module Control.Applicative.Permutations
(
Permutation,
runPermutation,
intercalateEffect,
toPermutation,
toPermutationWithDefault,
)
where
import Control.Applicative
import Data.Function ((&))
data Permutation m a = P !(Maybe a) [Branch m a]
data Branch m a = forall z. Branch (Permutation m (z -> a)) (m z)
instance Functor m => Functor (Permutation m) where
fmap :: forall a b. (a -> b) -> Permutation m a -> Permutation m b
fmap a -> b
f (P Maybe a
v [Branch m a]
bs) = forall (m :: * -> *) a. Maybe a -> [Branch m a] -> Permutation m a
P (a -> b
f forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Maybe a
v) (forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap a -> b
f forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> [Branch m a]
bs)
instance Functor p => Functor (Branch p) where
fmap :: forall a b. (a -> b) -> Branch p a -> Branch p b
fmap a -> b
f (Branch Permutation p (z -> a)
perm p z
p) = forall (m :: * -> *) a z.
Permutation m (z -> a) -> m z -> Branch m a
Branch (forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (a -> b
f forall b c a. (b -> c) -> (a -> b) -> a -> c
.) Permutation p (z -> a)
perm) p z
p
instance Functor m => Applicative (Permutation m) where
pure :: forall a. a -> Permutation m a
pure a
value = forall (m :: * -> *) a. Maybe a -> [Branch m a] -> Permutation m a
P (forall a. a -> Maybe a
Just a
value) forall (f :: * -> *) a. Alternative f => f a
empty
lhs :: Permutation m (a -> b)
lhs@(P Maybe (a -> b)
f [Branch m (a -> b)]
v) <*> :: forall a b.
Permutation m (a -> b) -> Permutation m a -> Permutation m b
<*> rhs :: Permutation m a
rhs@(P Maybe a
g [Branch m a]
w) = forall (m :: * -> *) a. Maybe a -> [Branch m a] -> Permutation m a
P (Maybe (a -> b)
f forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Maybe a
g) forall a b. (a -> b) -> a -> b
$ (forall {a}. Branch m (a -> a) -> Branch m a
ins2 forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> [Branch m (a -> b)]
v) forall a. Semigroup a => a -> a -> a
<> (Branch m a -> Branch m b
ins1 forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> [Branch m a]
w)
where
ins1 :: Branch m a -> Branch m b
ins1 (Branch Permutation m (z -> a)
perm m z
p) = forall (m :: * -> *) a z.
Permutation m (z -> a) -> m z -> Branch m a
Branch (forall b c a. (b -> c) -> (a -> b) -> a -> c
(.) forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Permutation m (a -> b)
lhs 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) = forall (m :: * -> *) a z.
Permutation m (z -> a) -> m z -> Branch m a
Branch (forall a b c. (a -> b -> c) -> b -> a -> c
flip forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Permutation m (z -> a -> a)
perm forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Permutation m a
rhs) m z
p
liftA2 :: forall a b c.
(a -> b -> c)
-> Permutation m a -> Permutation m b -> Permutation m c
liftA2 a -> 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) = forall (m :: * -> *) a. Maybe a -> [Branch m a] -> Permutation m a
P (forall (f :: * -> *) a b c.
Applicative f =>
(a -> b -> c) -> f a -> f b -> f c
liftA2 a -> b -> c
f Maybe a
x Maybe b
y) forall a b. (a -> b) -> a -> b
$ (Branch m a -> Branch m c
ins2 forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> [Branch m a]
v) forall a. Semigroup a => a -> a -> a
<> (Branch m b -> Branch m c
ins1 forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> [Branch m b]
w)
where
ins1 :: Branch m b -> Branch m c
ins1 (Branch Permutation m (z -> b)
perm m z
p) = forall (m :: * -> *) a z.
Permutation m (z -> a) -> m z -> Branch m a
Branch (forall (f :: * -> *) a b c.
Applicative f =>
(a -> b -> c) -> f a -> f b -> f c
liftA2 (forall b c a. (b -> c) -> (a -> b) -> a -> 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) = forall (m :: * -> *) a z.
Permutation m (z -> a) -> m z -> Branch m a
Branch (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
runPermutation ::
Alternative m =>
Permutation m a ->
m a
runPermutation :: forall (m :: * -> *) a. Alternative m => Permutation m a -> m a
runPermutation = forall (m :: * -> *) a.
Alternative m =>
(Branch m a -> m a) -> Permutation m a -> m a
foldAlt forall {m :: * -> *} {a}. Alternative m => Branch m a -> m a
f
where
f :: Branch m a -> m a
f (Branch Permutation m (z -> a)
t m z
p) = forall a b. a -> (a -> b) -> b
(&) forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> m z
p forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> forall (m :: * -> *) a. Alternative m => Permutation m a -> m a
runPermutation Permutation m (z -> a)
t
intercalateEffect ::
Alternative m =>
m b ->
Permutation m a ->
m a
intercalateEffect :: forall (m :: * -> *) b a.
Alternative m =>
m b -> Permutation m a -> m a
intercalateEffect m b
effect = forall (m :: * -> *) a.
Alternative m =>
(Branch m a -> m a) -> Permutation m a -> m a
foldAlt (forall (m :: * -> *) b a. Alternative m => m b -> Branch m a -> m a
runBranchEff m b
effect)
where
runPermEff :: Alternative m => m b -> Permutation m a -> m a
runPermEff :: forall (m :: * -> *) b a.
Alternative m =>
m b -> Permutation m a -> m a
runPermEff m b
eff (P Maybe a
v [Branch m a]
bs) =
m b
eff forall (f :: * -> *) a b. Applicative f => f a -> f b -> f b
*> forall (t :: * -> *) a b.
Foldable t =>
(a -> b -> b) -> b -> t a -> b
foldr (forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
(<|>) forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall (m :: * -> *) b a. Alternative m => m b -> Branch m a -> m a
runBranchEff m b
eff) forall (f :: * -> *) a. Alternative f => f a
empty [Branch m a]
bs forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> forall b a. b -> (a -> b) -> Maybe a -> b
maybe forall (f :: * -> *) a. Alternative f => f a
empty forall (f :: * -> *) a. Applicative f => a -> f a
pure Maybe a
v
runBranchEff :: Alternative m => m b -> Branch m a -> m a
runBranchEff :: forall (m :: * -> *) b a. Alternative m => m b -> Branch m a -> m a
runBranchEff m b
eff (Branch Permutation m (z -> a)
t m z
p) = forall a b. a -> (a -> b) -> b
(&) forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> m z
p forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> forall (m :: * -> *) b a.
Alternative m =>
m b -> Permutation m a -> m a
runPermEff m b
eff Permutation m (z -> a)
t
toPermutation ::
Alternative m =>
m a ->
Permutation m a
toPermutation :: forall (m :: * -> *) a. Alternative m => m a -> Permutation m a
toPermutation = forall (m :: * -> *) a. Maybe a -> [Branch m a] -> Permutation m a
P forall a. Maybe a
Nothing forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall (f :: * -> *) a. Applicative f => a -> f a
pure forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall (m :: * -> *) a. Functor m => m a -> Branch m a
branch
toPermutationWithDefault ::
Alternative m =>
a ->
m a ->
Permutation m a
toPermutationWithDefault :: forall (m :: * -> *) a.
Alternative m =>
a -> m a -> Permutation m a
toPermutationWithDefault a
v = forall (m :: * -> *) a. Maybe a -> [Branch m a] -> Permutation m a
P (forall a. a -> Maybe a
Just a
v) forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall (f :: * -> *) a. Applicative f => a -> f a
pure forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall (m :: * -> *) a. Functor m => m a -> Branch m a
branch
branch :: Functor m => m a -> Branch m a
branch :: forall (m :: * -> *) a. Functor m => m a -> Branch m a
branch = forall (m :: * -> *) a z.
Permutation m (z -> a) -> m z -> Branch m a
Branch forall a b. (a -> b) -> a -> b
$ forall (f :: * -> *) a. Applicative f => a -> f a
pure forall a. a -> a
id
foldAlt :: Alternative m => (Branch m a -> m a) -> Permutation m a -> m a
foldAlt :: forall (m :: * -> *) a.
Alternative m =>
(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) = forall (t :: * -> *) a b.
Foldable t =>
(a -> b -> b) -> b -> t a -> b
foldr (forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
(<|>) forall b c a. (b -> c) -> (a -> b) -> a -> c
. Branch m a -> m a
f) (forall b a. b -> (a -> b) -> Maybe a -> b
maybe forall (f :: * -> *) a. Alternative f => f a
empty forall (f :: * -> *) a. Applicative f => a -> f a
pure Maybe a
v) [Branch m a]
bs