packages feed

acts 0.2.0.0 → 0.3.0.0

raw patch · 5 files changed

+30/−277 lines, 5 filesdep +groupsdep −generic-dataPVP ok

version bump matches the API change (PVP)

Dependencies added: groups

Dependencies removed: generic-data

API changes (from Hackage documentation)

- Data.Group: (:|:) :: a -> Dual a -> Isom a
- Data.Group: [from] :: Isom a -> Dual a
- Data.Group: [to] :: Isom a -> a
- Data.Group: anti :: Group g => g -> Dual g
- Data.Group: class Monoid g => Group g
- Data.Group: data Isom a
- Data.Group: gtimes :: (Group g, Integral n) => n -> g -> g
- Data.Group: infix 7 :|:
- Data.Group: instance (Data.Group.GGroup f1, Data.Group.GGroup f2) => Data.Group.GGroup (f1 GHC.Generics.:*: f2)
- Data.Group: instance (Data.Group.Group (f1 p), Data.Group.Group (f2 p)) => Data.Group.Group ((GHC.Generics.:*:) f1 f2 p)
- Data.Group: instance (Data.Group.Group a, GHC.Base.Applicative f) => Data.Group.Group (Data.Monoid.Ap f a)
- Data.Group: instance (Data.Group.Group g1, Data.Group.Group g2) => Data.Group.Group (g1, g2)
- Data.Group: instance (Data.Group.Group g1, Data.Group.Group g2, Data.Group.Group g3) => Data.Group.Group (g1, g2, g3)
- Data.Group: instance (Data.Group.Group g1, Data.Group.Group g2, Data.Group.Group g3, Data.Group.Group g4) => Data.Group.Group (g1, g2, g3, g4)
- Data.Group: 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)
- Data.Group: 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)
- Data.Group: instance (TypeError ...) => Data.Group.GGroup (f1 GHC.Generics.:+: f2)
- Data.Group: instance (TypeError ...) => Data.Group.GGroup GHC.Generics.V1
- Data.Group: instance Control.DeepSeq.NFData a => Control.DeepSeq.NFData (Data.Group.Isom a)
- Data.Group: instance Data.Data.Data a => Data.Data.Data (Data.Group.Isom a)
- Data.Group: instance Data.Group.GGroup GHC.Generics.U1
- Data.Group: instance Data.Group.GGroup f => Data.Group.GGroup (GHC.Generics.M1 i c f)
- Data.Group: instance Data.Group.GGroup f => Data.Group.GGroup (GHC.Generics.Rec1 f)
- Data.Group: instance Data.Group.Group ()
- Data.Group: instance Data.Group.Group (Data.Proxy.Proxy p)
- Data.Group: instance Data.Group.Group (GHC.Generics.U1 p)
- Data.Group: instance Data.Group.Group (f p) => Data.Group.Group (GHC.Generics.M1 i c f p)
- Data.Group: instance Data.Group.Group (f p) => Data.Group.Group (GHC.Generics.Rec1 f p)
- Data.Group: instance Data.Group.Group a => Data.Group.Group (Data.Functor.Const.Const a b)
- Data.Group: instance Data.Group.Group a => Data.Group.Group (Data.Functor.Contravariant.Op a b)
- Data.Group: instance Data.Group.Group a => Data.Group.Group (Data.Functor.Identity.Identity a)
- Data.Group: instance Data.Group.Group a => Data.Group.Group (Data.Ord.Down a)
- Data.Group: instance Data.Group.Group a => Data.Group.Group (Data.Semigroup.Internal.Dual a)
- Data.Group: instance Data.Group.Group a => Data.Group.Group (GHC.ST.ST s a)
- Data.Group: instance Data.Group.Group a => Data.Group.Group (GHC.Types.IO a)
- Data.Group: instance Data.Group.Group a => Data.Group.Group (r -> a)
- Data.Group: instance Data.Group.Group g => Data.Group.GGroup (GHC.Generics.K1 i g)
- Data.Group: instance Data.Group.Group g => Data.Group.Group (GHC.Generics.K1 i g p)
- Data.Group: instance Data.Group.Group g => Data.Group.Group (GHC.Generics.Par1 g)
- Data.Group: instance GHC.Base.Monoid a => Data.Group.Group (Data.Group.Isom a)
- Data.Group: instance GHC.Base.Monoid a => GHC.Base.Monoid (Data.Group.Isom a)
- Data.Group: instance GHC.Base.Semigroup a => GHC.Base.Semigroup (Data.Group.Isom a)
- Data.Group: instance GHC.Generics.Generic (Data.Group.Isom a)
- Data.Group: instance GHC.Generics.Generic1 Data.Group.Isom
- Data.Group: instance GHC.Num.Num a => Data.Group.Group (Data.Semigroup.Internal.Sum a)
- Data.Group: instance GHC.Read.Read a => GHC.Read.Read (Data.Group.Isom a)
- Data.Group: instance GHC.Real.Fractional a => Data.Group.Group (Data.Semigroup.Internal.Product a)
- Data.Group: instance GHC.Show.Show a => GHC.Show.Show (Data.Group.Isom a)
- Data.Group: inverse :: Group g => g -> g
- Data.Group: reflexive :: Dual (Dual a) -> a
+ Data.Act: anti :: Group g => g -> Dual g
- Data.Act: infixr 5 •
+ Data.Act: infixr 5 `act`

Files

acts.cabal view
@@ -1,6 +1,6 @@ cabal-version:  2.4
 name:           acts
-version:        0.2.0.0
+version:        0.3.0.0
 synopsis:       Semigroup actions, groups, and torsors.
 category:       Algebra, Math
 license:        BSD-3-Clause
@@ -47,14 +47,12 @@   build-depends: 
       base
         >= 4.12 && < 4.15
-    , deepseq
-        ^>= 1.4.4.0
     , finitary
         ^>= 1.2.0.0
     , finite-typelits
         ^>= 0.1.4.2
-    , generic-data
-        >= 0.6.0.1 && < 0.7.0.0
+    , groups
+        ^>= 0.4.0.0
 
   default-language:
       Haskell2010
@@ -78,7 +76,10 @@ 
   exposed-modules:
       Data.Act
-    , Data.Group
+
+  build-depends:
+      deepseq
+        ^>= 1.4.4.0
 
 
 library acts-examples
changelog.md view
@@ -1,5 +1,10 @@ # Changelog for package `acts`
 
+## 0.3.0.0 ( February 16, 2020 )
+
+* Switch to using the `groups` package for the definition of the `Group` typeclass,
+splitting off the generic instances to the `groups-generic` package.
+
 ## 0.2.0.0 ( February 14, 2020 )
 
 * Remove definition of cyclic groups.
examples/Acts/Examples/MusicalIntervals.hs view
@@ -46,11 +46,13 @@ import Data.Finite
   ( Finite )
 
+-- groups
+import Data.Group
+  ( Group(..) )
+
 -- acts
 import Data.Act
   ( Act(..), Torsor(..), Finitely(..) )
-import Data.Group
-  ( Group(..) )
 
 -----------------------------------------------------------------
 -- * Musical notes
@@ -129,7 +131,7 @@ -- > > Steps ( Sum (-2) ) Natural
 -- > minor 3rd down
 --
--- > > inverse ( Steps ( Sum 2 ) Natural )
+-- > > invert ( Steps ( Sum 2 ) Natural )
 -- > Steps ( Sum (-2) ) Flat
 -- > major 3rd down
 
@@ -162,7 +164,7 @@ instance Monoid Interval where
   mempty = Steps mempty mempty
 instance Group Interval where
-  inverse = twist . inverse . straighten
+  invert = twist . invert . straighten
 
 -- | Intervallically correct action of intervals on notes.
 --
@@ -303,7 +305,7 @@       then ivalName
       else quality ival <> " " <> ivalName
     | i < 0
-    = quality ( inverse ival ) <> " " <> showOrdinal (-i+1) <> " down"
+    = quality ( invert ival ) <> " " <> showOrdinal (-i+1) <> " down"
     | otherwise
     = quality ival <> " " <> showOrdinal (i+1) <> " up"
 
src/Data/Act.hs view
@@ -2,13 +2,11 @@     DeriveGeneric
   , DeriveDataTypeable
   , DerivingVia
-  , FlexibleContexts
   , FlexibleInstances
   , GeneralizedNewtypeDeriving
   , MultiParamTypeClasses
   , ScopedTypeVariables
   , StandaloneDeriving
-  , TypeApplications
   , TypeFamilies
   , UndecidableInstances
 #-}
@@ -45,6 +43,7 @@   , transportAction
   , Trivial(..)
   , Torsor(..)
+  , anti
   , intertwiner
   , Finitely(..)
   )
@@ -81,9 +80,9 @@ import Data.Finite
   ( Finite )
 
--- acts
+-- groups
 import Data.Group
-  ( Group(..), anti )
+  ( Group(..) )
 
 -----------------------------------------------------------------
 
@@ -235,9 +234,16 @@ infix 7 -->
 infix 7 <--
 
+-- | A group's inversion anti-automorphism corresponds to an isomorphism to the opposite group.
+--
+-- The inversion allows us to obtain a left action from a right action (of the same group);
+-- the equivalent operation is not possible for general semigroups.
+anti :: Group g => g -> Dual g
+anti g = Dual ( invert g )
+
 -- | Any group is a torsor under its own natural left action.
 instance Group g => Torsor g g where
-  h <-- g = h <> inverse g
+  h <-- g = h <> invert g
 
 instance Num a => Torsor ( Sum a ) a where
   (<--) = coerce ( (<--) :: Sum a -> Sum a -> Sum a )
− src/Data/Group.hs
@@ -1,261 +0,0 @@-{-# LANGUAGE
-    DataKinds
-  , DeriveAnyClass
-  , DeriveDataTypeable
-  , DeriveGeneric
-  , DerivingVia
-  , GeneralizedNewtypeDeriving
-  , KindSignatures
-  , ScopedTypeVariables
-  , StandaloneDeriving
-  , TypeApplications
-  , TypeOperators
-  , UndecidableInstances
-#-}
-
-{-|
-Module: Data.Group
-
-A 'Group' is a 'Monoid' for which the monoid operation can be undone.
-
-That is, \( G \) is a group if each \( g \in G \) has an inverse element \( g^{ -1 } \) such that
-
-\[ g^{ -1 } < \! > g = \text{mempty} = g < \! > g^{ -1 } \]
-
-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
-
-- Use 'Generic' and 'Generic.Data.Generically':
-
-> > 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
-  ( Group(..), anti, reflexive
-  , Isom(..)
-  )
-  where
-
--- base
-import Control.Monad.ST
-  ( ST )
-import Data.Coerce
-  ( coerce )
-import Data.Data
-  ( Data )
-import Data.Functor.Const
-  ( Const(..) )
-import Data.Functor.Contravariant
-  ( Op(..) )
-import Data.Functor.Identity
-  ( Identity(..) )
-import Data.Monoid
-  ( Ap(..), Sum(..), Product(..) )
-import Data.Ord
-  ( Down(..) )
-import Data.Semigroup
-  ( Semigroup(..), Dual(..) )
-import Data.Proxy
-  ( Proxy(..) )
-import GHC.Generics
-  ( Generic, Generic1
-  , U1(..), Rec1(..), M1(..), K1(..), Par1(..), (:*:)(..)
-  , V1, (:+:)
-  )
-import qualified GHC.Generics as Generic
-  ( Generic(..) )
-import GHC.TypeLits
-  ( TypeError, ErrorMessage(Text) )
-
--- deepseq
-import Control.DeepSeq
-  ( NFData )
-
--- generic-data
-import Generic.Data
-  ( Generically(..) )
-
------------------------------------------------------------------------
-
--- | A 'Group' is a 'Monoid' with inverses:
---
--- * @ inverse g <> g = g <> inverse g = mempty @
---
--- * @ inverse (g <> h) = inverse h <> inverse g @
-class Monoid g => Group g where
-  {-# MINIMAL inverse | gtimes #-}
-  -- | Group inversion anti-homomorphism.
-  inverse :: g -> g
-  inverse = gtimes ( (-1) :: Int )
-
-  -- | Take the @n@-th power of an element.
-  gtimes :: Integral n => n -> g -> g
-  gtimes n = case compare n 0 of
-    EQ -> const mempty
-    GT -> stimes n
-    LT -> stimes ( negate n ) . inverse
-
--- | The inverse anti-automorphism of a group lifts to a isomorphism with the opposite group.
-anti :: Group g => g -> Dual g
-anti g = Dual ( inverse g )
-
--- | Reflexive property 'Dual' (should be included in base, maybe under another name).
-reflexive :: Dual ( Dual a ) -> a
-reflexive = coerce
-
------------------------------------------------------------------------
--- Instances.
-
--- | Trivial group.
-instance Group () where
-  inverse  _ = ()
-  gtimes _ _ = ()
-
--- | Additive groups (via 'Num').
-instance Num a => Group ( Sum a ) where
-  inverse  ( Sum a ) = Sum ( negate a )
-  gtimes n ( Sum a ) = Sum ( fromIntegral n * a )
-
--- | Multiplicative group (via 'Num').
-instance Fractional a => Group ( Product a ) where
-  inverse  ( Product a ) = Product ( recip a )
-  gtimes n ( Product a ) = Product ( a ^^ toInteger n )
-
--- | Opposite group.
-instance Group a => Group ( Dual a ) where
-  inverse  ( Dual a ) = Dual ( inverse a )
-  gtimes n ( Dual a ) = Dual ( gtimes n a )
-
--- | Lifting group operations through an applicative functor.
-instance ( Group a, Applicative f ) => Group ( Ap f a ) where
-  inverse  = fmap inverse
-  gtimes n = fmap ( gtimes n )
-
-deriving via Ap ((->) r) a instance Group a => Group ( r  ->  a )
-deriving via Ap IO       a instance Group a => Group ( IO     a )
-deriving via Ap (ST s)   a instance Group a => Group ( ST s   a )
-
-deriving newtype instance Group a => Group ( Down     a )
-deriving newtype instance Group a => Group ( Identity a )
-deriving newtype instance Group a => Group ( Const a b )
-deriving newtype instance Group a => Group ( Op    a b )
-
-instance Group ( Proxy p ) where
-  inverse  _ = Proxy
-  gtimes _ _ = Proxy
-
-instance ( Group g1, Group g2 )
-      => Group ( g1, g2 ) where
-  inverse  ( g1, g2 ) =
-    ( inverse g1, inverse g2 )
-  gtimes n ( g1, g2 ) =
-    ( gtimes n g1, gtimes n g2 )
-
-instance ( Group g1, Group g2, Group g3 )
-      => Group ( g1, g2, g3 ) where
-  inverse  ( g1, g2, g3 ) =
-    ( inverse g1, inverse g2, inverse g3 )
-  gtimes n ( g1, g2, g3 ) =
-    ( gtimes n g1, gtimes n g2, gtimes n g3 )
-
-instance ( Group g1, Group g2, Group g3, Group g4 )
-      => Group ( g1, g2, g3, g4 ) where
-  inverse  ( g1, g2, g3, g4 ) =
-    ( inverse g1, inverse g2, inverse g3, inverse g4 )
-  gtimes n ( g1, g2, g3, g4 ) =
-    ( gtimes n g1, gtimes n g2, gtimes n g3, gtimes n g4 )
-
-instance ( Group g1, Group g2, Group g3, Group g4, Group g5 )
-      => Group ( g1, g2, g3, g4, g5 ) where
-  inverse  ( g1, g2, g3, g4, g5 ) =
-    ( inverse g1, inverse g2, inverse g3, inverse g4, inverse g5 )
-  gtimes n ( g1, g2, g3, g4, g5 ) =
-    ( gtimes n g1, gtimes n g2, gtimes n g3, gtimes n g4, gtimes n g5 )
-
-infix 7 :|:
--- | Data type to keep track of a pair of inverse elements.
-data Isom a = (:|:) { to :: a, from :: Dual a }
-  deriving stock    ( Show, Read, Data, Generic, Generic1 )
-  deriving anyclass NFData
-instance Semigroup a => Semigroup ( Isom a ) where
-  ( p1 :|: q1 ) <> ( p2 :|: q2 ) = ( p1 <> p2 ) :|: ( q1 <> q2 )
-instance Monoid a => Monoid ( Isom a ) where
-  mempty = mempty :|: mempty
-instance Monoid a => Group ( Isom a ) where
-  inverse ( p :|: q ) = getDual q :|: Dual p
-
--- Generics.
-
-instance Group ( U1 p ) where
-  inverse  _ = U1
-  gtimes _ _ = U1
-
-deriving newtype instance Group ( f p ) => Group ( Rec1 f p )
-deriving newtype instance Group ( f p ) => Group ( M1 i c f p )
-deriving newtype instance Group g       => Group ( K1 i g p )
-deriving newtype instance Group g       => Group ( Par1 g )
-
-instance ( Group ( f1 p ), Group ( f2 p ) ) => Group ( (f1 :*: f2) p ) where
-  inverse  ( g1 :*: g2 ) = ( inverse  g1 :*: inverse  g2 )
-  gtimes n ( g1 :*: g2 ) = ( gtimes n g1 :*: gtimes n g2 )
-
-instance
-  ( Generic g
-  , Monoid  ( Generic.Rep g () )
-  , GGroup  ( Generic.Rep g )
-  )
-  => Group ( Generically g ) where
-  inverse  = Generically . Generic.to . ginverse  . Generic.from . unGenerically
-  gtimes n = Generically . Generic.to . ggtimes n . Generic.from . unGenerically
-
--- | Type class used for deriving 'Group' instances generically.
-class GGroup f where
-  ginverse :: f p -> f p
-  ggtimes  :: Integral n => n -> f p -> f p
-
-instance GGroup U1 where
-  ginverse  _ = U1
-  ggtimes _ _ = U1
-
-deriving newtype instance GGroup f => GGroup ( Rec1 f )
-deriving newtype instance GGroup f => GGroup ( M1 i c f )
-
-instance Group g => GGroup ( K1 i g ) where
-  ginverse  ( K1 g ) = K1 ( inverse  g )
-  ggtimes n ( K1 g ) = K1 ( gtimes n g )
-
-instance ( GGroup f1, GGroup f2 ) => GGroup ( f1 :*: f2 ) where
-  ginverse  ( g1 :*: g2 ) = ( ginverse  g1 :*: ginverse  g2 )
-  ggtimes n ( g1 :*: g2 ) = ( ggtimes n g1 :*: ggtimes n g2 )
-
-instance
-  TypeError ( 'Text "No 'Group' instance for empty generic representation." )
-  => GGroup V1 where
-  ginverse  _ = error "unreachable"
-  ggtimes _ _ = error "unreachable"
-
-instance
-  TypeError ( 'Text "No 'Group' instance for generic sum type." )
-  => GGroup ( f1 :+: f2 ) where
-  ginverse  _ = error "unreachable"
-  ggtimes _ _ = error "unreachable"