{-# LANGUAGE CPP #-}
{-# LANGUAGE ConstraintKinds #-}
{-# LANGUAGE DefaultSignatures #-}
{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE GADTs #-}
{-# LANGUAGE InstanceSigs #-}
{-# LANGUAGE PolyKinds #-}
{-# LANGUAGE RankNTypes #-}
{-# LANGUAGE ScopedTypeVariables #-}
{-# LANGUAGE TypeFamilies #-}
{-# LANGUAGE TypeApplications #-}
module Data.Algebra.Free
(
FreeAlgebra (..)
, Proof (..)
,
AlgebraType
, AlgebraType0
, unFoldMapFree
, foldFree
, natFree
, fmapFree
, joinFree
, bindFree
, cataFree
, foldrFree
, foldrFree'
, foldlFree
, foldlFree'
, Free (..)
, DNonEmpty (..)
)
where
import Prelude
import Data.DList as DList
import Data.Functor.Identity (Identity (..))
#if MIN_VERSION_data_fix(0,3,0)
import Data.Fix (Fix, foldFix)
#else
import Data.Fix (Fix, cata)
#endif
import Data.Group (Group (..))
import Data.Kind (Constraint, Type)
import Data.List.NonEmpty (NonEmpty (..))
import qualified Data.List.NonEmpty as NonEmpty
import Data.Monoid (Endo (..), Dual (..))
import Data.Algebra.Pointed (Pointed (..))
type family AlgebraType (f :: k) (a :: l) :: Constraint
type family AlgebraType0 (f :: k) (a :: l) :: Constraint
data Proof (c :: Constraint) (a :: l) where
Proof :: c => Proof c a
class FreeAlgebra (m :: Type -> Type) where
{-# MINIMAL returnFree, foldMapFree #-}
returnFree :: a -> m a
foldMapFree
:: forall d a
. ( AlgebraType m d
, AlgebraType0 m a
)
=> (a -> d)
-> (m a -> d)
codom :: forall a. AlgebraType0 m a => Proof (AlgebraType m (m a)) (m a)
default codom :: forall a. AlgebraType m (m a)
=> Proof (AlgebraType m (m a)) (m a)
codom = Proof (AlgebraType m (m a)) (m a)
forall {l} (c :: Constraint) (a :: l). c => Proof c a
Proof
forget :: forall a. AlgebraType m a => Proof (AlgebraType0 m a) (m a)
default forget :: forall a. AlgebraType0 m a
=> Proof (AlgebraType0 m a) (m a)
forget = Proof (AlgebraType0 m a) (m a)
forall {l} (c :: Constraint) (a :: l). c => Proof c a
Proof
unFoldMapFree
:: FreeAlgebra m
=> (m a -> d)
-> (a -> d)
unFoldMapFree :: forall (m :: * -> *) a d. FreeAlgebra m => (m a -> d) -> a -> d
unFoldMapFree m a -> d
f = m a -> d
f (m a -> d) -> (a -> m a) -> a -> d
forall b c a. (b -> c) -> (a -> b) -> a -> c
. a -> m a
forall a. a -> m a
forall (m :: * -> *) a. FreeAlgebra m => a -> m a
returnFree
{-# INLINABLE unFoldMapFree #-}
foldFree
:: forall m a .
( FreeAlgebra m
, AlgebraType m a
)
=> m a
-> a
foldFree :: forall (m :: * -> *) a.
(FreeAlgebra m, AlgebraType m a) =>
m a -> a
foldFree m a
ma = case forall (m :: * -> *) a.
(FreeAlgebra m, AlgebraType m a) =>
Proof (AlgebraType0 m a) (m a)
forget @m @a of
Proof (AlgebraType0 m a) (m a)
Proof -> (a -> a) -> m a -> a
forall d a.
(AlgebraType m d, AlgebraType0 m a) =>
(a -> d) -> m a -> d
forall (m :: * -> *) d a.
(FreeAlgebra m, AlgebraType m d, AlgebraType0 m a) =>
(a -> d) -> m a -> d
foldMapFree a -> a
forall a. a -> a
id m a
ma
{-# INLINABLE foldFree #-}
natFree :: forall m n a .
( FreeAlgebra m
, FreeAlgebra n
, AlgebraType0 m a
, AlgebraType m (n a)
)
=> m a
-> n a
natFree :: forall (m :: * -> *) (n :: * -> *) a.
(FreeAlgebra m, FreeAlgebra n, AlgebraType0 m a,
AlgebraType m (n a)) =>
m a -> n a
natFree = (a -> n a) -> m a -> n a
forall d a.
(AlgebraType m d, AlgebraType0 m a) =>
(a -> d) -> m a -> d
forall (m :: * -> *) d a.
(FreeAlgebra m, AlgebraType m d, AlgebraType0 m a) =>
(a -> d) -> m a -> d
foldMapFree a -> n a
forall a. a -> n a
forall (m :: * -> *) a. FreeAlgebra m => a -> m a
returnFree
{-# INLINABLE natFree #-}
fmapFree :: forall m a b .
( FreeAlgebra m
, AlgebraType0 m a
, AlgebraType0 m b
)
=> (a -> b)
-> m a
-> m b
fmapFree :: forall (m :: * -> *) a b.
(FreeAlgebra m, AlgebraType0 m a, AlgebraType0 m b) =>
(a -> b) -> m a -> m b
fmapFree a -> b
f m a
ma = case forall (m :: * -> *) a.
(FreeAlgebra m, AlgebraType0 m a) =>
Proof (AlgebraType m (m a)) (m a)
codom @m @b of
Proof (AlgebraType m (m b)) (m b)
Proof -> (a -> m b) -> m a -> m b
forall d a.
(AlgebraType m d, AlgebraType0 m a) =>
(a -> d) -> m a -> d
forall (m :: * -> *) d a.
(FreeAlgebra m, AlgebraType m d, AlgebraType0 m a) =>
(a -> d) -> m a -> d
foldMapFree (b -> m b
forall a. a -> m a
forall (m :: * -> *) a. FreeAlgebra m => a -> m a
returnFree (b -> m b) -> (a -> b) -> a -> m b
forall b c a. (b -> c) -> (a -> b) -> a -> c
. a -> b
f) m a
ma
{-# INLINABLE fmapFree #-}
joinFree :: forall m a .
( FreeAlgebra m
, AlgebraType0 m a
)
=> m (m a)
-> m a
joinFree :: forall (m :: * -> *) a.
(FreeAlgebra m, AlgebraType0 m a) =>
m (m a) -> m a
joinFree m (m a)
mma = case forall (m :: * -> *) a.
(FreeAlgebra m, AlgebraType0 m a) =>
Proof (AlgebraType m (m a)) (m a)
codom @m @a of
Proof (AlgebraType m (m a)) (m a)
Proof -> m (m a) -> m a
forall (m :: * -> *) a.
(FreeAlgebra m, AlgebraType m a) =>
m a -> a
foldFree m (m a)
mma
{-# INLINABLE joinFree #-}
bindFree :: forall m a b .
( FreeAlgebra m
, AlgebraType0 m a
, AlgebraType0 m b
)
=> m a
-> (a -> m b)
-> m b
bindFree :: forall (m :: * -> *) a b.
(FreeAlgebra m, AlgebraType0 m a, AlgebraType0 m b) =>
m a -> (a -> m b) -> m b
bindFree m a
ma a -> m b
f = case forall (m :: * -> *) a.
(FreeAlgebra m, AlgebraType0 m a) =>
Proof (AlgebraType m (m a)) (m a)
codom @m @b of
Proof (AlgebraType m (m b)) (m b)
Proof -> (a -> m b) -> m a -> m b
forall d a.
(AlgebraType m d, AlgebraType0 m a) =>
(a -> d) -> m a -> d
forall (m :: * -> *) d a.
(FreeAlgebra m, AlgebraType m d, AlgebraType0 m a) =>
(a -> d) -> m a -> d
foldMapFree a -> m b
f m a
ma
{-# INLINABLE bindFree #-}
cataFree :: ( FreeAlgebra m
, AlgebraType m a
, Functor m
)
=> Fix m
-> a
#if MIN_VERSION_data_fix(0,3,0)
cataFree :: forall (m :: * -> *) a.
(FreeAlgebra m, AlgebraType m a, Functor m) =>
Fix m -> a
cataFree = (m a -> a) -> Fix m -> a
forall (f :: * -> *) a. Functor f => (f a -> a) -> Fix f -> a
foldFix m a -> a
forall (m :: * -> *) a.
(FreeAlgebra m, AlgebraType m a) =>
m a -> a
foldFree
#else
cataFree = cata foldFree
#endif
foldrFree
:: forall m a b .
( FreeAlgebra m
, AlgebraType m (Endo b)
, AlgebraType0 m a
)
=> (a -> b -> b)
-> b
-> m a
-> b
foldrFree :: forall (m :: * -> *) a b.
(FreeAlgebra m, AlgebraType m (Endo b), AlgebraType0 m a) =>
(a -> b -> b) -> b -> m a -> b
foldrFree a -> b -> b
f b
z m a
t = Endo b -> b -> b
forall a. Endo a -> a -> a
appEndo ((a -> Endo b) -> m a -> Endo b
forall d a.
(AlgebraType m d, AlgebraType0 m a) =>
(a -> d) -> m a -> d
forall (m :: * -> *) d a.
(FreeAlgebra m, AlgebraType m d, AlgebraType0 m a) =>
(a -> d) -> m a -> d
foldMapFree ((b -> b) -> Endo b
forall a. (a -> a) -> Endo a
Endo ((b -> b) -> Endo b) -> (a -> b -> b) -> a -> Endo b
forall b c a. (b -> c) -> (a -> b) -> a -> c
. a -> b -> b
f) m a
t) b
z
foldrFree'
:: forall m a b .
( FreeAlgebra m
, AlgebraType m (Dual (Endo (b -> b)))
, AlgebraType0 m a
)
=> (a -> b -> b)
-> m a
-> b
-> b
foldrFree' :: forall (m :: * -> *) a b.
(FreeAlgebra m, AlgebraType m (Dual (Endo (b -> b))),
AlgebraType0 m a) =>
(a -> b -> b) -> m a -> b -> b
foldrFree' a -> b -> b
f m a
xs b
z0 = ((b -> b) -> a -> b -> b) -> (b -> b) -> m a -> b -> b
forall (m :: * -> *) a b.
(FreeAlgebra m, AlgebraType m (Dual (Endo b)), AlgebraType0 m a) =>
(b -> a -> b) -> b -> m a -> b
foldlFree (b -> b) -> a -> b -> b
f' b -> b
forall a. a -> a
id m a
xs b
z0
where
f' :: (b -> b) -> a -> b -> b
f' b -> b
k a
x b
z = b -> b
k (b -> b) -> b -> b
forall a b. (a -> b) -> a -> b
$! a -> b -> b
f a
x b
z
foldlFree
:: forall m a b .
( FreeAlgebra m
, AlgebraType m (Dual (Endo b))
, AlgebraType0 m a
)
=> (b -> a -> b)
-> b
-> m a
-> b
foldlFree :: forall (m :: * -> *) a b.
(FreeAlgebra m, AlgebraType m (Dual (Endo b)), AlgebraType0 m a) =>
(b -> a -> b) -> b -> m a -> b
foldlFree b -> a -> b
f b
z m a
t = Endo b -> b -> b
forall a. Endo a -> a -> a
appEndo (Dual (Endo b) -> Endo b
forall a. Dual a -> a
getDual ((a -> Dual (Endo b)) -> m a -> Dual (Endo b)
forall d a.
(AlgebraType m d, AlgebraType0 m a) =>
(a -> d) -> m a -> d
forall (m :: * -> *) d a.
(FreeAlgebra m, AlgebraType m d, AlgebraType0 m a) =>
(a -> d) -> m a -> d
foldMapFree (Endo b -> Dual (Endo b)
forall a. a -> Dual a
Dual (Endo b -> Dual (Endo b)) -> (a -> Endo b) -> a -> Dual (Endo b)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (b -> b) -> Endo b
forall a. (a -> a) -> Endo a
Endo ((b -> b) -> Endo b) -> (a -> b -> b) -> a -> Endo b
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (b -> a -> b) -> a -> b -> b
forall a b c. (a -> b -> c) -> b -> a -> c
flip b -> a -> b
f) m a
t)) b
z
foldlFree'
:: forall m a b .
( FreeAlgebra m
, AlgebraType m (Endo (b -> b))
, AlgebraType0 m a
)
=> (b -> a -> b)
-> b
-> m a
-> b
foldlFree' :: forall (m :: * -> *) a b.
(FreeAlgebra m, AlgebraType m (Endo (b -> b)), AlgebraType0 m a) =>
(b -> a -> b) -> b -> m a -> b
foldlFree' b -> a -> b
f b
z0 m a
xs = (a -> (b -> b) -> b -> b) -> (b -> b) -> m a -> b -> b
forall (m :: * -> *) a b.
(FreeAlgebra m, AlgebraType m (Endo b), AlgebraType0 m a) =>
(a -> b -> b) -> b -> m a -> b
foldrFree a -> (b -> b) -> b -> b
f' b -> b
forall a. a -> a
id m a
xs b
z0
where
f' :: a -> (b -> b) -> b -> b
f' a
x b -> b
k b
z = b -> b
k (b -> b) -> b -> b
forall a b. (a -> b) -> a -> b
$! b -> a -> b
f b
z a
x
type instance AlgebraType0 Identity a = ()
type instance AlgebraType Identity a = ()
instance FreeAlgebra Identity where
returnFree :: forall a. a -> Identity a
returnFree = a -> Identity a
forall a. a -> Identity a
Identity
foldMapFree :: forall d a.
(AlgebraType Identity d, AlgebraType0 Identity a) =>
(a -> d) -> Identity a -> d
foldMapFree a -> d
f = a -> d
f (a -> d) -> (Identity a -> a) -> Identity a -> d
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Identity a -> a
forall a. Identity a -> a
runIdentity
type instance AlgebraType0 NonEmpty a = ()
type instance AlgebraType NonEmpty m = Semigroup m
instance FreeAlgebra NonEmpty where
returnFree :: forall a. a -> NonEmpty a
returnFree a
a = a
a a -> [a] -> NonEmpty a
forall a. a -> [a] -> NonEmpty a
:| []
foldMapFree :: forall d a.
(AlgebraType NonEmpty d, AlgebraType0 NonEmpty a) =>
(a -> d) -> NonEmpty a -> d
foldMapFree a -> d
f (a
a :| []) = a -> d
f a
a
foldMapFree a -> d
f (a
a :| (a
b : [a]
bs)) = a -> d
f a
a d -> d -> d
forall a. Semigroup a => a -> a -> a
<> (a -> d) -> NonEmpty a -> d
forall d a.
(AlgebraType NonEmpty d, AlgebraType0 NonEmpty a) =>
(a -> d) -> NonEmpty a -> d
forall (m :: * -> *) d a.
(FreeAlgebra m, AlgebraType m d, AlgebraType0 m a) =>
(a -> d) -> m a -> d
foldMapFree a -> d
f (a
b a -> [a] -> NonEmpty a
forall a. a -> [a] -> NonEmpty a
:| [a]
bs)
newtype DNonEmpty a = DNonEmpty ([a] -> NonEmpty a)
instance Semigroup (DNonEmpty a) where
DNonEmpty [a] -> NonEmpty a
f <> :: DNonEmpty a -> DNonEmpty a -> DNonEmpty a
<> DNonEmpty [a] -> NonEmpty a
g = ([a] -> NonEmpty a) -> DNonEmpty a
forall a. ([a] -> NonEmpty a) -> DNonEmpty a
DNonEmpty ([a] -> NonEmpty a
f ([a] -> NonEmpty a) -> ([a] -> [a]) -> [a] -> NonEmpty a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. NonEmpty a -> [a]
forall a. NonEmpty a -> [a]
NonEmpty.toList (NonEmpty a -> [a]) -> ([a] -> NonEmpty a) -> [a] -> [a]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [a] -> NonEmpty a
g)
type instance AlgebraType0 DNonEmpty a = ()
type instance AlgebraType DNonEmpty m = Semigroup m
instance FreeAlgebra DNonEmpty where
returnFree :: forall a. a -> DNonEmpty a
returnFree a
a = ([a] -> NonEmpty a) -> DNonEmpty a
forall a. ([a] -> NonEmpty a) -> DNonEmpty a
DNonEmpty (a
a a -> [a] -> NonEmpty a
forall a. a -> [a] -> NonEmpty a
:|)
foldMapFree :: forall d a.
(AlgebraType DNonEmpty d, AlgebraType0 DNonEmpty a) =>
(a -> d) -> DNonEmpty a -> d
foldMapFree a -> d
f (DNonEmpty [a] -> NonEmpty a
g) = (a -> d) -> NonEmpty a -> d
forall d a.
(AlgebraType NonEmpty d, AlgebraType0 NonEmpty a) =>
(a -> d) -> NonEmpty a -> d
forall (m :: * -> *) d a.
(FreeAlgebra m, AlgebraType m d, AlgebraType0 m a) =>
(a -> d) -> m a -> d
foldMapFree a -> d
f ([a] -> NonEmpty a
g [])
type instance AlgebraType0 [] a = ()
type instance AlgebraType [] m = Monoid m
instance FreeAlgebra [] where
returnFree :: forall a. a -> [a]
returnFree a
a = [a
a]
foldMapFree :: forall d a.
(AlgebraType [] d, AlgebraType0 [] a) =>
(a -> d) -> [a] -> d
foldMapFree = (a -> d) -> [a] -> d
forall m a. Monoid m => (a -> m) -> [a] -> m
forall (t :: * -> *) m a.
(Foldable t, Monoid m) =>
(a -> m) -> t a -> m
foldMap
type instance AlgebraType0 Maybe a = ()
type instance AlgebraType Maybe m = Pointed m
instance FreeAlgebra Maybe where
returnFree :: forall a. a -> Maybe a
returnFree = a -> Maybe a
forall a. a -> Maybe a
Just
foldMapFree :: forall d a.
(AlgebraType Maybe d, AlgebraType0 Maybe a) =>
(a -> d) -> Maybe a -> d
foldMapFree a -> d
_ Maybe a
Nothing = d
forall p. Pointed p => p
point
foldMapFree a -> d
f (Just a
a) = a -> d
f a
a
newtype Free (c :: Type -> Constraint) a = Free {
forall (c :: * -> Constraint) a.
Free c a -> forall r. c r => (a -> r) -> r
runFree :: forall r. c r => (a -> r) -> r
}
instance Semigroup (Free Semigroup a) where
Free forall r. Semigroup r => (a -> r) -> r
f <> :: Free Semigroup a -> Free Semigroup a -> Free Semigroup a
<> Free forall r. Semigroup r => (a -> r) -> r
g = (forall r. Semigroup r => (a -> r) -> r) -> Free Semigroup a
forall (c :: * -> Constraint) a.
(forall r. c r => (a -> r) -> r) -> Free c a
Free ((forall r. Semigroup r => (a -> r) -> r) -> Free Semigroup a)
-> (forall r. Semigroup r => (a -> r) -> r) -> Free Semigroup a
forall a b. (a -> b) -> a -> b
$ \a -> r
k -> (a -> r) -> r
forall r. Semigroup r => (a -> r) -> r
f a -> r
k r -> r -> r
forall a. Semigroup a => a -> a -> a
<> (a -> r) -> r
forall r. Semigroup r => (a -> r) -> r
g a -> r
k
type instance AlgebraType0 (Free Semigroup) a = ()
type instance AlgebraType (Free Semigroup) a = Semigroup a
instance FreeAlgebra (Free Semigroup) where
returnFree :: forall a. a -> Free Semigroup a
returnFree a
a = (forall r. Semigroup r => (a -> r) -> r) -> Free Semigroup a
forall (c :: * -> Constraint) a.
(forall r. c r => (a -> r) -> r) -> Free c a
Free ((forall r. Semigroup r => (a -> r) -> r) -> Free Semigroup a)
-> (forall r. Semigroup r => (a -> r) -> r) -> Free Semigroup a
forall a b. (a -> b) -> a -> b
$ \a -> r
k -> a -> r
k a
a
foldMapFree :: forall d a.
(AlgebraType (Free Semigroup) d,
AlgebraType0 (Free Semigroup) a) =>
(a -> d) -> Free Semigroup a -> d
foldMapFree a -> d
f (Free forall r. Semigroup r => (a -> r) -> r
k) = (a -> d) -> d
forall r. Semigroup r => (a -> r) -> r
k a -> d
f
instance Semigroup (Free Monoid a) where
Free forall r. Monoid r => (a -> r) -> r
f <> :: Free Monoid a -> Free Monoid a -> Free Monoid a
<> Free forall r. Monoid r => (a -> r) -> r
g = (forall r. Monoid r => (a -> r) -> r) -> Free Monoid a
forall (c :: * -> Constraint) a.
(forall r. c r => (a -> r) -> r) -> Free c a
Free ((forall r. Monoid r => (a -> r) -> r) -> Free Monoid a)
-> (forall r. Monoid r => (a -> r) -> r) -> Free Monoid a
forall a b. (a -> b) -> a -> b
$ \a -> r
k -> (a -> r) -> r
forall r. Monoid r => (a -> r) -> r
f a -> r
k r -> r -> r
forall a. Monoid a => a -> a -> a
`mappend` (a -> r) -> r
forall r. Monoid r => (a -> r) -> r
g a -> r
k
instance Monoid (Free Monoid a) where
mempty :: Free Monoid a
mempty = (forall r. Monoid r => (a -> r) -> r) -> Free Monoid a
forall (c :: * -> Constraint) a.
(forall r. c r => (a -> r) -> r) -> Free c a
Free (r -> (a -> r) -> r
forall a b. a -> b -> a
const r
forall a. Monoid a => a
mempty)
#if __GLASGOW_HASKELL__ <= 802
mappend = (<>)
#endif
type instance AlgebraType0 (Free Monoid) a = ()
type instance AlgebraType (Free Monoid) a = Monoid a
instance FreeAlgebra (Free Monoid) where
returnFree :: forall a. a -> Free Monoid a
returnFree a
a = (forall r. Monoid r => (a -> r) -> r) -> Free Monoid a
forall (c :: * -> Constraint) a.
(forall r. c r => (a -> r) -> r) -> Free c a
Free ((forall r. Monoid r => (a -> r) -> r) -> Free Monoid a)
-> (forall r. Monoid r => (a -> r) -> r) -> Free Monoid a
forall a b. (a -> b) -> a -> b
$ \a -> r
k -> a -> r
k a
a
foldMapFree :: forall d a.
(AlgebraType (Free Monoid) d, AlgebraType0 (Free Monoid) a) =>
(a -> d) -> Free Monoid a -> d
foldMapFree a -> d
f (Free forall r. Monoid r => (a -> r) -> r
k) = (a -> d) -> d
forall r. Monoid r => (a -> r) -> r
k a -> d
f
type instance AlgebraType0 DList a = ()
type instance AlgebraType DList a = Monoid a
instance FreeAlgebra DList where
returnFree :: forall a. a -> DList a
returnFree = a -> DList a
forall a. a -> DList a
DList.singleton
foldMapFree :: forall d a.
(AlgebraType DList d, AlgebraType0 DList a) =>
(a -> d) -> DList a -> d
foldMapFree = (a -> d) -> DList a -> d
forall m a. Monoid m => (a -> m) -> DList a -> m
forall (t :: * -> *) m a.
(Foldable t, Monoid m) =>
(a -> m) -> t a -> m
foldMap
instance Semigroup (Free Group a) where
Free forall r. Group r => (a -> r) -> r
f <> :: Free Group a -> Free Group a -> Free Group a
<> Free forall r. Group r => (a -> r) -> r
g = (forall r. Group r => (a -> r) -> r) -> Free Group a
forall (c :: * -> Constraint) a.
(forall r. c r => (a -> r) -> r) -> Free c a
Free ((forall r. Group r => (a -> r) -> r) -> Free Group a)
-> (forall r. Group r => (a -> r) -> r) -> Free Group a
forall a b. (a -> b) -> a -> b
$ \a -> r
k -> (a -> r) -> r
forall r. Group r => (a -> r) -> r
f a -> r
k r -> r -> r
forall a. Monoid a => a -> a -> a
`mappend` (a -> r) -> r
forall r. Group r => (a -> r) -> r
g a -> r
k
instance Monoid (Free Group a) where
mempty :: Free Group a
mempty = (forall r. Group r => (a -> r) -> r) -> Free Group a
forall (c :: * -> Constraint) a.
(forall r. c r => (a -> r) -> r) -> Free c a
Free (r -> (a -> r) -> r
forall a b. a -> b -> a
const r
forall a. Monoid a => a
mempty)
#if __GLASGOW_HASKELL__ <= 802
mappend = (<>)
#endif
instance Group (Free Group a) where
invert :: Free Group a -> Free Group a
invert (Free forall r. Group r => (a -> r) -> r
k) = (forall r. Group r => (a -> r) -> r) -> Free Group a
forall (c :: * -> Constraint) a.
(forall r. c r => (a -> r) -> r) -> Free c a
Free ((a -> r) -> r
forall r. Group r => (a -> r) -> r
k ((a -> r) -> r) -> ((a -> r) -> a -> r) -> (a -> r) -> r
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (a -> r) -> a -> r
forall m. Group m => m -> m
invert)
type instance AlgebraType0 (Free Group) a = ()
type instance AlgebraType (Free Group) a = Group a
instance FreeAlgebra (Free Group) where
returnFree :: forall a. a -> Free Group a
returnFree a
a = (forall r. Group r => (a -> r) -> r) -> Free Group a
forall (c :: * -> Constraint) a.
(forall r. c r => (a -> r) -> r) -> Free c a
Free ((forall r. Group r => (a -> r) -> r) -> Free Group a)
-> (forall r. Group r => (a -> r) -> r) -> Free Group a
forall a b. (a -> b) -> a -> b
$ \a -> r
k -> a -> r
k a
a
foldMapFree :: forall d a.
(AlgebraType (Free Group) d, AlgebraType0 (Free Group) a) =>
(a -> d) -> Free Group a -> d
foldMapFree a -> d
f (Free forall r. Group r => (a -> r) -> r
k) = (a -> d) -> d
forall r. Group r => (a -> r) -> r
k a -> d
f