{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE MultiParamTypeClasses #-}
module Data.Monoid.Action
( Action(..)
, Regular(..)
, Conjugate(..)
, Torsor(..)
) where
import Data.Functor.Identity (Identity(Identity))
import Data.Semigroup
import qualified Data.Semigroup as Semigroup
import Data.Group
import qualified Data.Monoid as Monoid
import Data.Void (Void, absurd)
class Action m s where
act :: m -> s -> s
act = (s -> s) -> m -> s -> s
forall a b. a -> b -> a
const s -> s
forall a. a -> a
id
instance Action () l where
act :: () -> l -> l
act () = l -> l
forall a. a -> a
id
instance Action m s => Action (Maybe m) s where
act :: Maybe m -> s -> s
act Maybe m
Nothing s
s = s
s
act (Just m
m) s
s = m -> s -> s
forall m s. Action m s => m -> s -> s
act m
m s
s
instance Action m s => Action [m] s where
act :: [m] -> s -> s
act = (s -> [m] -> s) -> [m] -> s -> s
forall a b c. (a -> b -> c) -> b -> a -> c
flip ((m -> s -> s) -> s -> [m] -> s
forall a b. (a -> b -> b) -> b -> [a] -> b
forall (t :: * -> *) a b.
Foldable t =>
(a -> b -> b) -> b -> t a -> b
foldr m -> s -> s
forall m s. Action m s => m -> s -> s
act)
instance Action (Endo a) a where
act :: Endo a -> a -> a
act = Endo a -> a -> a
forall a. Endo a -> a -> a
appEndo
instance Num a => Action Integer (Sum a) where
Integer
n act :: Integer -> Sum a -> Sum a
`act` Sum a
a = Integer -> Sum a
forall a. Num a => Integer -> a
fromInteger Integer
n Sum a -> Sum a -> Sum a
forall a. Semigroup a => a -> a -> a
<> Sum a
a
instance Num a => Action Integer (Product a) where
Integer
n act :: Integer -> Product a -> Product a
`act` Product a
a = Integer -> Product a
forall a. Num a => Integer -> a
fromInteger Integer
n Product a -> Product a -> Product a
forall a. Semigroup a => a -> a -> a
<> Product a
a
instance Fractional a => Action Rational (Sum a) where
Rational
n act :: Rational -> Sum a -> Sum a
`act` Sum a
a = a -> Sum a
forall a. a -> Sum a
Sum (Rational -> a
forall a. Fractional a => Rational -> a
fromRational Rational
n) Sum a -> Sum a -> Sum a
forall a. Semigroup a => a -> a -> a
<> Sum a
a
instance Fractional a => Action Rational (Product a) where
Rational
n act :: Rational -> Product a -> Product a
`act` Product a
a = a -> Product a
forall a. a -> Product a
Product (Rational -> a
forall a. Fractional a => Rational -> a
fromRational Rational
n) Product a -> Product a -> Product a
forall a. Semigroup a => a -> a -> a
<> Product a
a
class Group m => Torsor m s where
difference :: s -> s -> m
newtype Regular m = Regular { forall m. Regular m -> m
getRegular :: m }
instance Semigroup m => Action m (Regular m) where
m
m1 act :: m -> Regular m -> Regular m
`act` Regular m
m2 = m -> Regular m
forall m. m -> Regular m
Regular (m -> Regular m) -> m -> Regular m
forall a b. (a -> b) -> a -> b
$ m
m1 m -> m -> m
forall a. Semigroup a => a -> a -> a
<> m
m2
instance Group m => Torsor m (Regular m) where
Regular m
m1 difference :: Regular m -> Regular m -> m
`difference` Regular m
m2 = m
m1 m -> m -> m
forall m. Group m => m -> m -> m
~~ m
m2
newtype Conjugate m = Conjugate { forall m. Conjugate m -> m
getConjugate :: m }
instance Group m => Action m (Conjugate m) where
m
m1 act :: m -> Conjugate m -> Conjugate m
`act` Conjugate m
m2 = m -> Conjugate m
forall m. m -> Conjugate m
Conjugate (m -> Conjugate m) -> m -> Conjugate m
forall a b. (a -> b) -> a -> b
$ m
m1 m -> m -> m
forall a. Semigroup a => a -> a -> a
<> m
m2 m -> m -> m
forall m. Group m => m -> m -> m
~~ m
m1
instance Action (Semigroup.First a) a where
act :: First a -> a -> a
act (Semigroup.First a
m) a
_ = a
m
instance Action (Monoid.First a) a where
act :: First a -> a -> a
act (Monoid.First Maybe a
m) a
s = case Maybe a
m of
Maybe a
Nothing -> a
s
Just a
m' -> a
m'
instance Action Void a where
act :: Void -> a -> a
act = Void -> a -> a
forall a. Void -> a
absurd
instance Action m s => Action (Identity m) s where
act :: Identity m -> s -> s
act (Identity m
m) = m -> s -> s
forall m s. Action m s => m -> s -> s
act m
m