-- Hoogle documentation, generated by Haddock
-- See Hoogle, http://www.haskell.org/hoogle/
-- | Semigroup actions, groups, and torsors.
--
-- Acts and torsors model types which can be transformed under the action
-- of another type.
--
-- A prototypical example is affine space, which has an action by
-- translation: given any two points in affine space, there is a unique
-- translation that brings one to the other.
--
-- This can be useful in a library keeping track of time: on top of
-- needing to keep track of units, one also needs to distinguish between
-- absolute time (time stamps) and relative time (time differences). The
-- operations one expects in this situation are:
--
--
-- - Addition and subtraction of time differences: time differences
-- form a (commutative) group.
-- - Translation of an absolute time by a time difference: there is an
-- action of relative time on absolute time.
-- - Given two absolute times, one can obtain the time difference
-- between them: absolute time is a torsor under relative time.
--
--
-- This library provides a convenient framework which helps to avoid
-- mixing up these two different notions.
--
-- A fleshed out example is available at
-- Acts.Examples.MusicalIntervals, which showcases the use of
-- actions and torsors in the context of musical intervals and harmony.
-- It also demonstrates common usage patterns of this library, such as
-- how to automatically derive instances.
--
-- See also the project readme, which includes a simple example with 2D
-- affine space.
@package acts
@version 0.1.0.0
-- | A Group is a Monoid for which the monoid operation can
-- be undone.
--
-- That is, <math> is a group if each <math> has an inverse
-- element <math> such that
--
-- <math>
--
-- Such inverses are necessarily unique.
--
-- In Haskell, groups are mostly useful to describe objects possessing
-- certain symmetries (such as translation or rotation).
--
-- To automatically derive Group instances, you can:
--
--
-- - Use DerivingVia to coerce an existing instance:
--
--
--
-- > newtype Seconds = Seconds { getSeconds :: Double }
-- > newtype TimeDelta = TimeDelta { timeDeltaInSeconds :: Seconds }
-- > deriving ( Semigroup, Monoid, Group )
-- > via Sum Double
--
--
--
--
--
-- > data MyRecord
-- > = MyRecord
-- > { field1 :: Sum Double
-- > , field2 :: Product Double
-- > , field3 :: Ap [] ( Sum Int, Sum Int )
-- > }
-- > deriving Generic
-- > deriving ( Semigroup, Monoid, Group )
-- > via Generically MyRecord
--
module Data.Group
-- | A Group is a Monoid with inverses:
--
--
class Monoid g => Group g
-- | Group inversion anti-homomorphism.
inverse :: Group g => g -> g
-- | Take the n-th power of an element.
gtimes :: (Group g, Integral n) => n -> g -> g
-- | Data type to keep track of a pair of inverse elements.
data Isom a
(:|:) :: a -> Dual a -> Isom a
[to] :: Isom a -> a
[from] :: Isom a -> Dual a
infix 7 :|:
instance Control.DeepSeq.NFData a => Control.DeepSeq.NFData (Data.Group.Isom a)
instance GHC.Generics.Generic1 Data.Group.Isom
instance GHC.Generics.Generic (Data.Group.Isom a)
instance Data.Data.Data a => Data.Data.Data (Data.Group.Isom a)
instance GHC.Read.Read a => GHC.Read.Read (Data.Group.Isom a)
instance GHC.Show.Show a => GHC.Show.Show (Data.Group.Isom a)
instance Data.Group.Group a => Data.Group.Group (r -> a)
instance Data.Group.Group a => Data.Group.Group (GHC.Types.IO a)
instance Data.Group.Group a => Data.Group.Group (GHC.ST.ST s a)
instance Data.Group.Group a => Data.Group.Group (Data.Ord.Down a)
instance Data.Group.Group a => Data.Group.Group (Data.Functor.Identity.Identity a)
instance Data.Group.Group a => Data.Group.Group (Data.Functor.Const.Const a b)
instance Data.Group.Group a => Data.Group.Group (Data.Functor.Contravariant.Op a b)
instance Data.Group.Group (f p) => Data.Group.Group (GHC.Generics.Rec1 f p)
instance Data.Group.Group (f p) => Data.Group.Group (GHC.Generics.M1 i c f p)
instance Data.Group.Group g => Data.Group.Group (GHC.Generics.K1 i g p)
instance Data.Group.Group g => Data.Group.Group (GHC.Generics.Par1 g)
instance Data.Group.GGroup f => Data.Group.GGroup (GHC.Generics.Rec1 f)
instance Data.Group.GGroup f => Data.Group.GGroup (GHC.Generics.M1 i c f)
instance (GHC.Generics.Generic g, GHC.Base.Monoid (GHC.Generics.Rep g ()), Data.Group.GGroup (GHC.Generics.Rep g)) => Data.Group.Group (Generic.Data.Internal.Generically.Generically g)
instance Data.Group.GGroup GHC.Generics.U1
instance Data.Group.Group g => Data.Group.GGroup (GHC.Generics.K1 i g)
instance (Data.Group.GGroup f1, Data.Group.GGroup f2) => Data.Group.GGroup (f1 GHC.Generics.:*: f2)
instance (TypeError ...) => Data.Group.GGroup GHC.Generics.V1
instance (TypeError ...) => Data.Group.GGroup (f1 GHC.Generics.:+: f2)
instance GHC.Base.Semigroup a => GHC.Base.Semigroup (Data.Group.Isom a)
instance GHC.Base.Monoid a => GHC.Base.Monoid (Data.Group.Isom a)
instance GHC.Base.Monoid a => Data.Group.Group (Data.Group.Isom a)
instance Data.Group.Group ()
instance GHC.Num.Num a => Data.Group.Group (Data.Semigroup.Internal.Sum a)
instance GHC.Real.Fractional a => Data.Group.Group (Data.Semigroup.Internal.Product a)
instance Data.Group.Group a => Data.Group.Group (Data.Semigroup.Internal.Dual a)
instance (Data.Group.Group a, GHC.Base.Applicative f) => Data.Group.Group (Data.Monoid.Ap f a)
instance Data.Group.Group (Data.Proxy.Proxy p)
instance (Data.Group.Group g1, Data.Group.Group g2) => Data.Group.Group (g1, g2)
instance (Data.Group.Group g1, Data.Group.Group g2, Data.Group.Group g3) => Data.Group.Group (g1, g2, g3)
instance (Data.Group.Group g1, Data.Group.Group g2, Data.Group.Group g3, Data.Group.Group g4) => Data.Group.Group (g1, g2, g3, g4)
instance (Data.Group.Group g1, Data.Group.Group g2, Data.Group.Group g3, Data.Group.Group g4, Data.Group.Group g5) => Data.Group.Group (g1, g2, g3, g4, g5)
instance Data.Group.Group (GHC.Generics.U1 p)
instance (Data.Group.Group (f1 p), Data.Group.Group (f2 p)) => Data.Group.Group ((GHC.Generics.:*:) f1 f2 p)
-- | An Act of a semigroup <math> on a type <math> gives
-- a way to transform terms of type <math> by terms of type
-- <math>, in a way that is compatible with the semigroup operation
-- on <math>.
--
-- In the special case that there is a unique way of going from one term
-- of type <math> to another through a transformation by a term of
-- type <math>, we say that <math> is a torsor under
-- <math>.
--
-- For example, the plane has an action by translations. Given any two
-- points, there is a unique translation that takes the first point to
-- the second. Note that an unmarked plane (like a blank piece of paper)
-- has no designated origin or reference point, whereas the set of
-- translations is a plane with a given origin (the zero translation).
-- This is the distinction between an affine space (an unmarked plane)
-- and a vector space. Enforcing this distinction in the types can help
-- to avoid confusing absolute points with translation vectors.
--
-- Simple Act and Torsor instances can be derived through
-- self-actions:
--
--
-- > newtype Seconds = Seconds { getSeconds :: Double }
-- > deriving ( Act TimeDelta, Torsor TimeDelta )
-- > via TimeDelta
-- > newtype TimeDelta = TimeDelta { timeDeltaInSeconds :: Seconds }
-- > deriving ( Semigroup, Monoid, Group )
-- > via Sum Double
--
module Data.Act
-- | A left act (or left semigroup action) of a semigroup
-- s on x consists of an operation
--
--
-- (•) :: s -> x -> x
--
--
-- such that:
--
--
-- a • ( b • x ) = ( a <> b ) • x
--
--
-- In case s is also a Monoid, we additionally require:
--
--
-- mempty • x = x
--
--
-- The synonym act = (•) is also provided.
class Semigroup s => Act s x
-- | Left action of a semigroup.
(•) :: Act s x => s -> x -> x
-- | Left action of a semigroup.
act :: Act s x => s -> x -> x
infixr 5 `act`
infixr 5 •
-- | Transport an act:
--
transportAction :: (a -> b) -> (b -> a) -> (g -> b -> b) -> g -> a -> a
-- | Trivial act of a semigroup on any type (acting by the identity).
newtype Trivial a
Trivial :: a -> Trivial a
[getTrivial] :: Trivial a -> a
-- | A left torsor consists of a free and transitive
-- left action of a group on an inhabited type.
--
-- This precisely means that for any two terms x, y,
-- there exists a unique group element g taking
-- x to y, which is denoted y <-- x (or
-- x --> y , but the left-pointing arrow is more natural
-- when working with left actions).
--
-- That is y <-- x is the unique element satisfying:
--
--
-- ( y <-- x ) • x = y
--
--
-- Note the order of composition of <-- and -->
-- with respect to <>:
--
--
-- ( z <-- y ) <> ( y <-- x ) = z <-- x
--
--
--
-- ( y --> z ) <> ( x --> y ) = x --> z
--
class (Group g, Act g x) => Torsor g x
-- | Unique group element effecting the given transition
(<--) :: Torsor g x => x -> x -> g
-- | Unique group element effecting the given transition
(-->) :: Torsor g x => x -> x -> g
infix 7 -->
infix 7 <--
-- | Given
--
--
-- - <math> acting on <math>,
-- - <math> a torsor under <math>,
-- - a map <math>,
--
--
-- this function returns the unique element <math> making the
-- following diagram commute:
--
intertwiner :: forall h g a b. (Act g a, Torsor h b) => g -> (a -> b) -> a -> h
instance Control.DeepSeq.NFData a => Control.DeepSeq.NFData (Data.Act.Trivial a)
instance GHC.Enum.Bounded a => GHC.Enum.Bounded (Data.Act.Trivial a)
instance GHC.Enum.Enum a => GHC.Enum.Enum (Data.Act.Trivial a)
instance GHC.Classes.Ord a => GHC.Classes.Ord (Data.Act.Trivial a)
instance GHC.Classes.Eq a => GHC.Classes.Eq (Data.Act.Trivial a)
instance GHC.Generics.Generic1 Data.Act.Trivial
instance GHC.Generics.Generic (Data.Act.Trivial a)
instance Data.Data.Data a => Data.Data.Data (Data.Act.Trivial a)
instance GHC.Read.Read a => GHC.Read.Read (Data.Act.Trivial a)
instance GHC.Show.Show a => GHC.Show.Show (Data.Act.Trivial a)
instance Data.Act.Act Data.Semigroup.Internal.Any GHC.Types.Bool
instance Data.Act.Act Data.Semigroup.Internal.All GHC.Types.Bool
instance GHC.Num.Num a => Data.Act.Act (Data.Semigroup.Internal.Sum a) a
instance GHC.Num.Num a => Data.Act.Act (Data.Semigroup.Internal.Product a) a
instance GHC.Classes.Ord a => Data.Act.Act (Data.Semigroup.Max a) a
instance GHC.Classes.Ord a => Data.Act.Act (Data.Semigroup.Min a) a
instance Data.Act.Act s a => Data.Act.Act s (Data.Functor.Const.Const a b)
instance GHC.Num.Num a => Data.Act.Torsor (Data.Semigroup.Internal.Sum a) a
instance Data.Group.Group g => Data.Act.Torsor g g
instance GHC.Base.Semigroup s => Data.Act.Act s (Data.Act.Trivial a)
instance GHC.Base.Semigroup s => Data.Act.Act s s
instance Data.Act.Act () x
instance (Data.Act.Act s1 x1, Data.Act.Act s2 x2) => Data.Act.Act (s1, s2) (x1, x2)
instance (Data.Act.Act s1 x1, Data.Act.Act s2 x2, Data.Act.Act s3 x3) => Data.Act.Act (s1, s2, s3) (x1, x2, x3)
instance (Data.Act.Act s1 x1, Data.Act.Act s2 x2, Data.Act.Act s3 x3, Data.Act.Act s4 x4) => Data.Act.Act (s1, s2, s3, s4) (x1, x2, x3, x4)
instance (Data.Act.Act s1 x1, Data.Act.Act s2 x2, Data.Act.Act s3 x3, Data.Act.Act s4 x4, Data.Act.Act s5 x5) => Data.Act.Act (s1, s2, s3, s4, s5) (x1, x2, x3, x4, x5)
instance (Data.Act.Act s x, GHC.Base.Functor f) => Data.Act.Act s (Data.Monoid.Ap f x)
instance (GHC.Base.Semigroup s, Data.Act.Act s a) => Data.Act.Act (Data.Semigroup.Internal.Dual s) (Data.Functor.Contravariant.Op b a)
instance (GHC.Base.Semigroup s, Data.Act.Act s a, Data.Act.Act t b) => Data.Act.Act (Data.Semigroup.Internal.Dual s, t) (a -> b)
instance (Data.Act.Act g x, Data.Group.Group g) => Data.Act.Act (Data.Semigroup.Internal.Dual g) x
instance (Data.Group.Group g, Data.Act.Act g a) => Data.Act.Act g (Data.Semigroup.Internal.Endo a)
-- | Cyclic groups: integers modulo n (clock arithmetic).
module Data.Group.Cyclic
-- | Cyclic group of order n: integers with addition modulo
-- n.
data Cyclic n
-- | Smart pattern and constructor for elements of cyclic groups.
pattern Cyclic :: forall n. KnownNat n => Int -> Cyclic n
-- | Obtain a representative in the range <math>.
getCyclic :: forall n. KnownNat n => Cyclic n -> Int
-- | Synonym for finite cyclic group.
type C (n :: Nat) = Cyclic n
-- | Synonym for infinite cyclic group.
type Z = Sum Int
-- | Newtype for cycling through elements in a finite enumeration.
--
--
-- data ABCD = A | B | C | D
-- deriving stock ( Enum, Bounded )
-- deriving ( Act ( Cyclic 4 ), Torsor ( Cyclic 4 ) )
-- via CyclicEnum ABCD
--
--
--
-- > act ( Cyclic 2 ) C
-- A
--
--
--
-- > act ( Cyclic (-1) ) A
-- D
--
--
--
-- > ( C --> B :: Cyclic 4 )
-- Cyclic 3
--
--
-- Warning It is unfortunately not checked that the size of the
-- group matches the size of the finite enumeration. Please manually
-- ensure this condition.
newtype CyclicEnum a
CyclicEnum :: a -> CyclicEnum a
[getCyclicEnum] :: CyclicEnum a -> a
-- | Nontrivial element of cyclic group of order 2.
pattern Involution :: Cyclic 2
-- | Act by an involution.
involution :: Act (Cyclic 2) x => x -> x
-- | Natural complex representations of finite cyclic groups as roots of
-- unity.
rootOfUnity :: forall a n. (KnownNat n, Floating a) => Cyclic n -> Complex a
instance Control.DeepSeq.NFData (Data.Group.Cyclic.Cyclic n)
instance GHC.TypeNats.KnownNat n => GHC.Enum.Bounded (Data.Group.Cyclic.Cyclic n)
instance GHC.TypeNats.KnownNat n => GHC.Enum.Enum (Data.Group.Cyclic.Cyclic n)
instance GHC.Classes.Ord (Data.Group.Cyclic.Cyclic n)
instance GHC.Classes.Eq (Data.Group.Cyclic.Cyclic n)
instance GHC.Generics.Generic1 Data.Group.Cyclic.Cyclic
instance GHC.Generics.Generic (Data.Group.Cyclic.Cyclic n)
instance GHC.Show.Show (Data.Group.Cyclic.Cyclic n)
instance Control.DeepSeq.NFData a => Control.DeepSeq.NFData (Data.Group.Cyclic.CyclicEnum a)
instance GHC.Enum.Bounded a => GHC.Enum.Bounded (Data.Group.Cyclic.CyclicEnum a)
instance GHC.Enum.Enum a => GHC.Enum.Enum (Data.Group.Cyclic.CyclicEnum a)
instance GHC.Classes.Ord a => GHC.Classes.Ord (Data.Group.Cyclic.CyclicEnum a)
instance GHC.Classes.Eq a => GHC.Classes.Eq (Data.Group.Cyclic.CyclicEnum a)
instance GHC.Generics.Generic1 Data.Group.Cyclic.CyclicEnum
instance GHC.Generics.Generic (Data.Group.Cyclic.CyclicEnum a)
instance Data.Data.Data a => Data.Data.Data (Data.Group.Cyclic.CyclicEnum a)
instance GHC.Show.Show a => GHC.Show.Show (Data.Group.Cyclic.CyclicEnum a)
instance GHC.TypeNats.KnownNat n => GHC.Base.Semigroup (Data.Group.Cyclic.Cyclic n)
instance (GHC.TypeNats.KnownNat n, 1 GHC.TypeNats.<= n) => GHC.Base.Monoid (Data.Group.Cyclic.Cyclic n)
instance (GHC.TypeNats.KnownNat n, 1 GHC.TypeNats.<= n) => Data.Group.Group (Data.Group.Cyclic.Cyclic n)
instance (GHC.Enum.Enum a, GHC.Enum.Bounded a, GHC.TypeNats.KnownNat n) => Data.Act.Act (Data.Group.Cyclic.Cyclic n) (Data.Group.Cyclic.CyclicEnum a)
instance (GHC.Enum.Enum a, GHC.Enum.Bounded a, GHC.TypeNats.KnownNat n, 1 GHC.TypeNats.<= n) => Data.Act.Torsor (Data.Group.Cyclic.Cyclic n) (Data.Group.Cyclic.CyclicEnum a)
instance GHC.TypeNats.KnownNat n => Data.Act.Act (Data.Group.Cyclic.Cyclic n) GHC.Types.Int
instance Data.Act.Act (Data.Group.Cyclic.Cyclic 2) GHC.Types.Bool
instance GHC.Num.Num i => Data.Act.Act (Data.Group.Cyclic.Cyclic 2) (Data.Semigroup.Internal.Sum i)
instance GHC.Real.Fractional i => Data.Act.Act (Data.Group.Cyclic.Cyclic 2) (Data.Semigroup.Internal.Product i)
instance GHC.Num.Num a => Data.Act.Act (Data.Group.Cyclic.Cyclic 2) (Data.Complex.Complex a)