{-# LANGUAGE ConstraintKinds #-}
{-# LANGUAGE RankNTypes #-}
{-# LANGUAGE Safe #-}
module Algebra.Lattice.Free.Final (
FLattice,
liftFLattice,
lowerFLattice,
retractFLattice,
FBoundedLattice,
liftFBoundedLattice,
lowerFBoundedLattice,
retractFBoundedLattice,
) where
import Prelude ()
import Prelude.Compat
import Algebra.Lattice
import Data.Universe.Class (Finite (..), Universe (..))
newtype FLattice a = FLattice
{ lowerFLattice :: forall b. Lattice b =>
(a -> b) -> b
}
instance Functor FLattice where
fmap f (FLattice g) = FLattice (\inj -> g (inj . f))
a <$ FLattice f = FLattice (\inj -> f (const (inj a)))
liftFLattice :: a -> FLattice a
liftFLattice a = FLattice (\inj -> inj a)
retractFLattice :: Lattice a => FLattice a -> a
retractFLattice a = lowerFLattice a id
instance Lattice (FLattice a) where
FLattice f \/ FLattice g = FLattice (\inj -> f inj \/ g inj)
FLattice f /\ FLattice g = FLattice (\inj -> f inj /\ g inj)
instance BoundedJoinSemiLattice a =>
BoundedJoinSemiLattice (FLattice a) where
bottom = FLattice (\inj -> inj bottom)
instance BoundedMeetSemiLattice a =>
BoundedMeetSemiLattice (FLattice a) where
top = FLattice (\inj -> inj top)
instance Universe a => Universe (FLattice a) where
universe = fmap liftFLattice universe
instance Finite a => Finite (FLattice a) where
universeF = fmap liftFLattice universeF
newtype FBoundedLattice a = FBoundedLattice
{ lowerFBoundedLattice :: forall b. BoundedLattice b =>
(a -> b) -> b
}
instance Functor FBoundedLattice where
fmap f (FBoundedLattice g) = FBoundedLattice (\inj -> g (inj . f))
a <$ FBoundedLattice f = FBoundedLattice (\inj -> f (const (inj a)))
liftFBoundedLattice :: a -> FBoundedLattice a
liftFBoundedLattice a = FBoundedLattice (\inj -> inj a)
retractFBoundedLattice :: BoundedLattice a => FBoundedLattice a -> a
retractFBoundedLattice a = lowerFBoundedLattice a id
instance Lattice (FBoundedLattice a) where
FBoundedLattice f \/ FBoundedLattice g = FBoundedLattice (\inj -> f inj \/ g inj)
FBoundedLattice f /\ FBoundedLattice g = FBoundedLattice (\inj -> f inj /\ g inj)
instance BoundedJoinSemiLattice (FBoundedLattice a) where
bottom = FBoundedLattice (\_ -> bottom)
instance BoundedMeetSemiLattice (FBoundedLattice a) where
top = FBoundedLattice (\_ -> top)
instance Universe a => Universe (FBoundedLattice a) where
universe = fmap liftFBoundedLattice universe
instance Finite a => Finite (FBoundedLattice a) where
universeF = fmap liftFBoundedLattice universeF