lr-acts-0.2: src/Data/Semidirect/Strict.hs
-----------------------------------------------------------------------------
-- |
-- Module : Data.Semidirect.Strict
-- Description : Strict semidirect products
-- Copyright : (c) Alice Rixte 2025
-- License : BSD 3
-- Maintainer : alice.rixte@u-bordeaux.fr
-- Stability : unstable
-- Portability : non-portable (GHC extensions)
--
-- Semidirect products for left and right actions.
--
-- For a lazy version, see "Data.Semidirect.Lazy".
--
-- [Usage :]
--
-- >>> import Data.Semigroup
-- >>> LPair (Sum 1) (Product 2) <> LPair (Sum (3 :: Int)) (Product (4 :: Int))
-- LPair {lactee = Sum {getSum = 7}, lactor = Product {getProduct = 8}}
--
-- [Property checking :]
--
-- There is a @'Semigroup'@ instance for @'LSemidirect'@ (resp. @'RSemidirect'@)
-- only if there is a @'LActSgMorph'@ (resp. @'RActSgMorph'@) instance. For
-- example, @'Sum' Int@ acting on itself is not a semigroup action by morphism
-- and therefore the semidirect product is not associative :
--
-- >>> LPair (Sum 1) (Sum 2) <> LPair (Sum (3 :: Int)) (Sum (4 :: Int))
-- No instance for `LActDistrib (Sum Int) (Sum Int)'
-- arising from a use of `<>'
--
-----------------------------------------------------------------------------
module Data.Semidirect.Strict
( LSemidirect (..)
, lvacate
, lerase
, lreset
, lforget
, lfromActor
, lembedActee
, lfromActee
, lembedActor
, lfromPair
, RSemidirect (..)
, rreset
, rerase
, rvacate
, rforget
, rfromActor
, rembedActee
, rfromActee
, rembedActor
, rfromPair
) where
import Data.Bifunctor
import Data.Act
-- | A semi-direct product for a left action, where @s@ acts on @x@
--
data LSemidirect x s = LPair
{ lactee :: !x -- ^ The value being acted on
, lactor :: !s -- ^ The acting element
}
deriving (Show, Read, Eq)
instance LActSgMorph x s
=> Semigroup (LSemidirect x s) where
LPair x s <> LPair x' s' =
LPair (x <> (s <>$ x')) (s <> s')
instance LActMnMorph x s => Monoid (LSemidirect x s) where
mempty = LPair mempty mempty
instance Functor (LSemidirect x) where
fmap f a = a {lactor = f (lactor a)}
instance Bifunctor LSemidirect where
first f a = a {lactee = f (lactee a)}
second = fmap
-- | Replace the actee with @mempty@.
lvacate :: Monoid x => LSemidirect x s -> LSemidirect x s
lvacate a = a {lactee = mempty}
-- | Erase the actee (i.e. replace it with @mempty@).
lerase :: Monoid x => LSemidirect x s -> LSemidirect x s
lerase a = a {lactee = mempty}
{-# DEPRECATED lerase "Use lvacate instead." #-}
-- | Replace the actor with @mempty@.
lreset :: Monoid s => LSemidirect x s -> LSemidirect x s
lreset a = a {lactor = mempty}
-- | Forget the actor (i.e. replace it with @mempty@).
lforget :: Monoid s => LSemidirect x s -> LSemidirect x s
lforget a =a {lactor = mempty}
{-# DEPRECATED lforget "Use lreset instead." #-}
-- | Make a semidirect pair whose actee is @mempty@.
lfromActor :: Monoid x => s -> LSemidirect x s
lfromActor s = LPair mempty s
-- | Make a semidirect pair whose actee is @mempty@.
lembedActor :: Monoid x => s -> LSemidirect x s
lembedActor s = LPair mempty s
{-# DEPRECATED lembedActor "Use lfromActor instead." #-}
-- | Make a semidirect pair whose actor is @mempty@.
lfromActee :: Monoid s => x -> LSemidirect x s
lfromActee x = LPair x mempty
-- | Make a semidirect pair whose actor is @mempty@.
lembedActee :: Monoid s => x -> LSemidirect x s
lembedActee x = LPair x mempty
{-# DEPRECATED lembedActee "Use lfromActee instead." #-}
-- | Convert a pair into a semidirect product element.
lfromPair :: (x,s) -> LSemidirect x s
lfromPair (x,s) = LPair x s
------------------------------------------------------------------------------
-- | A semidirect product for a right action, where @s@ acts on @x@
--
data RSemidirect x s = RPair
{ ractee :: !x -- ^ The value being acted on
, ractor :: !s -- ^ The acting element
}
deriving (Show, Read, Eq)
instance RActSgMorph x s
=> Semigroup (RSemidirect x s) where
RPair x s <> RPair x' s' =
RPair (x <> (x' $<> s)) (s <> s')
instance RActMnMorph x s => Monoid (RSemidirect x s) where
mempty = RPair mempty mempty
instance Functor (RSemidirect x) where
fmap f a = a {ractor = f (ractor a)}
instance Bifunctor RSemidirect where
first f a = a {ractee = f (ractee a)}
second = fmap
-- | Replace the actee with @mempty@.
rvacate :: Monoid x => RSemidirect x s -> RSemidirect x s
rvacate a = a {ractee = mempty}
-- | Erase the actee (i.e. replace it with @mempty@).
rerase :: Monoid x => RSemidirect x s -> RSemidirect x s
rerase a = a {ractee = mempty}
{-# DEPRECATED rerase "Use rvacate instead." #-}
-- | Replace the actor with @mempty@.
rreset :: Monoid s => RSemidirect x s -> RSemidirect x s
rreset a = a {ractor = mempty}
-- | Forget the actor (i.e. replace it with @mempty@).
rforget :: Monoid s => RSemidirect x s -> RSemidirect x s
rforget a = a {ractor = mempty}
{-# DEPRECATED rforget "Use rreset instead." #-}
-- | Make a semidirect pair whose actee is @mempty@.
rfromActor :: Monoid x => s -> RSemidirect x s
rfromActor s = RPair mempty s
-- | Make a semidirect pair whose actee is @mempty@.
rembedActor :: Monoid x => s -> RSemidirect x s
rembedActor s = RPair mempty s
{-# DEPRECATED rembedActor "Use rfromActor instead." #-}
-- | Make a semidirect pair whose actor is @mempty@.
rfromActee :: Monoid s => x -> RSemidirect x s
rfromActee x = RPair x mempty
-- | Make a semidirect pair whose actor element is @mempty@ .
rembedActee :: Monoid s => x -> RSemidirect x s
rembedActee x = RPair x mempty
{-# DEPRECATED rembedActee "Use rfromActee instead." #-}
-- | Convert a pair into a semidirect product element
rfromPair :: (x,s) -> RSemidirect x s
rfromPair (x,s) = RPair x s