{-# LANGUAGE RankNTypes #-}
module Algebra.Lattice.Free
(
FreeJoinSemiLattice
, liftFreeJoinSemiLattice
, lowerFreeJoinSemiLattice
, retractFreeJoinSemiLattice
, FreeMeetSemiLattice
, liftFreeMeetSemiLattice
, lowerFreeMeetSemiLattice
, retractFreeMeetSemiLattice
, FreeLattice
, liftFreeLattice
, lowerFreeLattice
, retractFreeLattice
) where
import Prelude ()
import Prelude.Compat
import Algebra.Lattice
import Data.Universe.Class
newtype FreeJoinSemiLattice a = FreeJoinSemiLattice
{ lowerFreeJoinSemiLattice :: forall b. JoinSemiLattice b =>
(a -> b) -> b
}
liftFreeJoinSemiLattice :: a -> FreeJoinSemiLattice a
liftFreeJoinSemiLattice a = FreeJoinSemiLattice (\inj -> inj a)
retractFreeJoinSemiLattice :: JoinSemiLattice a => FreeJoinSemiLattice a -> a
retractFreeJoinSemiLattice a = lowerFreeJoinSemiLattice a id
instance Functor FreeJoinSemiLattice where
fmap f (FreeJoinSemiLattice g) = FreeJoinSemiLattice (\inj -> g (inj . f))
a <$ FreeJoinSemiLattice f = FreeJoinSemiLattice (\inj -> f (const (inj a)))
instance JoinSemiLattice (FreeJoinSemiLattice a) where
FreeJoinSemiLattice f \/ FreeJoinSemiLattice g =
FreeJoinSemiLattice (\inj -> f inj \/ g inj)
instance BoundedJoinSemiLattice a =>
BoundedJoinSemiLattice (FreeJoinSemiLattice a) where
bottom = FreeJoinSemiLattice (\inj -> inj bottom)
instance Universe a => Universe (FreeJoinSemiLattice a) where
universe = fmap liftFreeJoinSemiLattice universe
instance Finite a => Finite (FreeJoinSemiLattice a) where
universeF = fmap liftFreeJoinSemiLattice universeF
newtype FreeMeetSemiLattice a = FreeMeetSemiLattice
{ lowerFreeMeetSemiLattice :: forall b. MeetSemiLattice b =>
(a -> b) -> b
}
instance Functor FreeMeetSemiLattice where
fmap f (FreeMeetSemiLattice g) = FreeMeetSemiLattice (\inj -> g (inj . f))
a <$ FreeMeetSemiLattice f = FreeMeetSemiLattice (\inj -> f (const (inj a)))
liftFreeMeetSemiLattice :: a -> FreeMeetSemiLattice a
liftFreeMeetSemiLattice a = FreeMeetSemiLattice (\inj -> inj a)
retractFreeMeetSemiLattice :: MeetSemiLattice a => FreeMeetSemiLattice a -> a
retractFreeMeetSemiLattice a = lowerFreeMeetSemiLattice a id
instance MeetSemiLattice (FreeMeetSemiLattice a) where
FreeMeetSemiLattice f /\ FreeMeetSemiLattice g =
FreeMeetSemiLattice (\inj -> f inj /\ g inj)
instance BoundedMeetSemiLattice a =>
BoundedMeetSemiLattice (FreeMeetSemiLattice a) where
top = FreeMeetSemiLattice (\inj -> inj top)
instance Universe a => Universe (FreeMeetSemiLattice a) where
universe = fmap liftFreeMeetSemiLattice universe
instance Finite a => Finite (FreeMeetSemiLattice a) where
universeF = fmap liftFreeMeetSemiLattice universeF
newtype FreeLattice a = FreeLattice
{ lowerFreeLattice :: forall b. Lattice b =>
(a -> b) -> b
}
instance Functor FreeLattice where
fmap f (FreeLattice g) = FreeLattice (\inj -> g (inj . f))
a <$ FreeLattice f = FreeLattice (\inj -> f (const (inj a)))
liftFreeLattice :: a -> FreeLattice a
liftFreeLattice a = FreeLattice (\inj -> inj a)
retractFreeLattice :: Lattice a => FreeLattice a -> a
retractFreeLattice a = lowerFreeLattice a id
instance JoinSemiLattice (FreeLattice a) where
FreeLattice f \/ FreeLattice g = FreeLattice (\inj -> f inj \/ g inj)
instance MeetSemiLattice (FreeLattice a) where
FreeLattice f /\ FreeLattice g = FreeLattice (\inj -> f inj /\ g inj)
instance Lattice (FreeLattice a)
instance BoundedJoinSemiLattice a =>
BoundedJoinSemiLattice (FreeLattice a) where
bottom = FreeLattice (\inj -> inj bottom)
instance BoundedMeetSemiLattice a =>
BoundedMeetSemiLattice (FreeLattice a) where
top = FreeLattice (\inj -> inj top)
instance BoundedLattice a =>
BoundedLattice (FreeLattice a)
instance Universe a => Universe (FreeLattice a) where
universe = fmap liftFreeLattice universe
instance Finite a => Finite (FreeLattice a) where
universeF = fmap liftFreeLattice universeF