More algebraic structure
- Dominant language
- Haskell
- Stars
- 135
- Forks
- 83
- PR merge metrics
- No merged PRs in 30d
Description
Not sure exactly how best to do this, but something like:
```
instance Semigroup DiffTime
instance Monoid DiffTime
instance Semigroup NominalDiffTime
instance Monoid NominalDiffTime
class Monoid a => Group a where
negateG :: a -> a
(~~) :: a -> a -> a
scaleG :: Int -> a -> a
instance Num a => Group (Sum a) -- but what about Natural?
instance Group DiffTime
instance Group NominalDiffTime
class Group (TorsorGroup a) => Torsor a where
type TorsorGroup a :: *
addT :: TorsorGroup a -> a -> a
diffT :: a -> a -> TorsorGroup a
instance Torsor Day where
type Torsor Day = Sum Integer
...
instance Torsor UTCTime where
type Torsor UTCTime = NominalDiffTime
...
-- etc. for other time types
```
## Notes
Using this as a scratch-pad for ideas, editing often.
1. See [Baez](https://math.ucr.edu/home/baez/torsors.html) to get the gist of torsors.
1. See also #281, although this and that can be done independently.
1. `Torsor` and especially `Group` are generally useful classes; it might be a bit odd to define them in the time library.
1. Should also do #277 with this.
1. A stricter definition of `Group` would be `class (Monoid a, Torsor a, TorsorGroup a ~ a) => Group a`, not sure if that's too annoying.
- Alternatively can do `instance {-# OVERLAPPABLE #-} Group a => Torsor a where ...`
1. There's a bit of tension between the concepts "monoid" and "additive monoid" (likewise "group", etc.), and we use the `Sum` type to bridge the gap. For example there isn't an `instance Monoid Integer` (using addition) because there can be other monoids on `Integer`.
1. This sort of thing has been attempted elsewhere:
- [torsor](https://hackage.haskell.org/package/torsor)
- [monoid-extras](https://hackage.haskell.org/package/monoid-extras)
- [lr-acts](https://hackage.haskell.org/package/lr-acts)
1. A nice way of looking at some of the classes is to consider the domain of the scaling function `:: i -> a -> a`:
- `i` is the positive integers: semigroup
- `i` is the non-negative integers: monoid
- `i` is the integers: group
- `i` is the rationals or reals: one-dimension vector space over rationals or reals
1. There probably isn't a need to add a "one-dimension vector space" class (what members would it have?) even though `UTCTime` would morally be an instance.
Expanding on point 5, it is possible to collapse `Group` into `Torsor`:
```
class Group (TorsorGroup a) => Torsor a where
type TorsorGroup a :: *
addT :: TorsorGroup a -> a -> a
(~~) :: a -> a -> TorsorGroup a
type Group a = (Monoid a, Torsor a, TorsorGroup a ~ a)
negateG :: Group a => a -> a
negateG x = mempty ~~ x
```
Contributor guide
No contributing guide indexed for this repository
Assessment
This issue has not been assessed yet.