{-# LANGUAGE DeriveTraversable #-}
{-# LANGUAGE TupleSections #-}
{-# LANGUAGE AllowAmbiguousTypes #-}
{-# LANGUAGE ScopedTypeVariables #-}
{-# LANGUAGE TypeApplications #-}
{-# LANGUAGE GADTs #-}
{-# LANGUAGE MultiParamTypeClasses, ConstraintKinds, FlexibleContexts, FlexibleInstances, DeriveGeneric #-}

module Algebra.Morphism.Exponential where

import Prelude (Show,Eq,Ord,Integer,Functor,Foldable)
import Data.Traversable
import Algebra.Classes

newtype Exp a = Exp a deriving (Int -> Exp a -> ShowS
[Exp a] -> ShowS
Exp a -> String
(Int -> Exp a -> ShowS)
-> (Exp a -> String) -> ([Exp a] -> ShowS) -> Show (Exp a)
forall a. Show a => Int -> Exp a -> ShowS
forall a. Show a => [Exp a] -> ShowS
forall a. Show a => Exp a -> String
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: forall a. Show a => Int -> Exp a -> ShowS
showsPrec :: Int -> Exp a -> ShowS
$cshow :: forall a. Show a => Exp a -> String
show :: Exp a -> String
$cshowList :: forall a. Show a => [Exp a] -> ShowS
showList :: [Exp a] -> ShowS
Show,Exp a -> Exp a -> Bool
(Exp a -> Exp a -> Bool) -> (Exp a -> Exp a -> Bool) -> Eq (Exp a)
forall a. Eq a => Exp a -> Exp a -> Bool
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: forall a. Eq a => Exp a -> Exp a -> Bool
== :: Exp a -> Exp a -> Bool
$c/= :: forall a. Eq a => Exp a -> Exp a -> Bool
/= :: Exp a -> Exp a -> Bool
Eq,Eq (Exp a)
Eq (Exp a) =>
(Exp a -> Exp a -> Ordering)
-> (Exp a -> Exp a -> Bool)
-> (Exp a -> Exp a -> Bool)
-> (Exp a -> Exp a -> Bool)
-> (Exp a -> Exp a -> Bool)
-> (Exp a -> Exp a -> Exp a)
-> (Exp a -> Exp a -> Exp a)
-> Ord (Exp a)
Exp a -> Exp a -> Bool
Exp a -> Exp a -> Ordering
Exp a -> Exp a -> Exp a
forall a.
Eq a =>
(a -> a -> Ordering)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> a)
-> (a -> a -> a)
-> Ord a
forall a. Ord a => Eq (Exp a)
forall a. Ord a => Exp a -> Exp a -> Bool
forall a. Ord a => Exp a -> Exp a -> Ordering
forall a. Ord a => Exp a -> Exp a -> Exp a
$ccompare :: forall a. Ord a => Exp a -> Exp a -> Ordering
compare :: Exp a -> Exp a -> Ordering
$c< :: forall a. Ord a => Exp a -> Exp a -> Bool
< :: Exp a -> Exp a -> Bool
$c<= :: forall a. Ord a => Exp a -> Exp a -> Bool
<= :: Exp a -> Exp a -> Bool
$c> :: forall a. Ord a => Exp a -> Exp a -> Bool
> :: Exp a -> Exp a -> Bool
$c>= :: forall a. Ord a => Exp a -> Exp a -> Bool
>= :: Exp a -> Exp a -> Bool
$cmax :: forall a. Ord a => Exp a -> Exp a -> Exp a
max :: Exp a -> Exp a -> Exp a
$cmin :: forall a. Ord a => Exp a -> Exp a -> Exp a
min :: Exp a -> Exp a -> Exp a
Ord,(forall m. Monoid m => Exp m -> m)
-> (forall m a. Monoid m => (a -> m) -> Exp a -> m)
-> (forall m a. Monoid m => (a -> m) -> Exp a -> m)
-> (forall a b. (a -> b -> b) -> b -> Exp a -> b)
-> (forall a b. (a -> b -> b) -> b -> Exp a -> b)
-> (forall b a. (b -> a -> b) -> b -> Exp a -> b)
-> (forall b a. (b -> a -> b) -> b -> Exp a -> b)
-> (forall a. (a -> a -> a) -> Exp a -> a)
-> (forall a. (a -> a -> a) -> Exp a -> a)
-> (forall a. Exp a -> [a])
-> (forall a. Exp a -> Bool)
-> (forall a. Exp a -> Int)
-> (forall a. Eq a => a -> Exp a -> Bool)
-> (forall a. Ord a => Exp a -> a)
-> (forall a. Ord a => Exp a -> a)
-> (forall a. Num a => Exp a -> a)
-> (forall a. Num a => Exp a -> a)
-> Foldable Exp
forall a. Eq a => a -> Exp a -> Bool
forall a. Num a => Exp a -> a
forall a. Ord a => Exp a -> a
forall m. Monoid m => Exp m -> m
forall a. Exp a -> Bool
forall a. Exp a -> Int
forall a. Exp a -> [a]
forall a. (a -> a -> a) -> Exp a -> a
forall m a. Monoid m => (a -> m) -> Exp a -> m
forall b a. (b -> a -> b) -> b -> Exp a -> b
forall a b. (a -> b -> b) -> b -> Exp a -> b
forall (t :: * -> *).
(forall m. Monoid m => t m -> m)
-> (forall m a. Monoid m => (a -> m) -> t a -> m)
-> (forall m a. Monoid m => (a -> m) -> t a -> m)
-> (forall a b. (a -> b -> b) -> b -> t a -> b)
-> (forall a b. (a -> b -> b) -> b -> t a -> b)
-> (forall b a. (b -> a -> b) -> b -> t a -> b)
-> (forall b a. (b -> a -> b) -> b -> t a -> b)
-> (forall a. (a -> a -> a) -> t a -> a)
-> (forall a. (a -> a -> a) -> t a -> a)
-> (forall a. t a -> [a])
-> (forall a. t a -> Bool)
-> (forall a. t a -> Int)
-> (forall a. Eq a => a -> t a -> Bool)
-> (forall a. Ord a => t a -> a)
-> (forall a. Ord a => t a -> a)
-> (forall a. Num a => t a -> a)
-> (forall a. Num a => t a -> a)
-> Foldable t
$cfold :: forall m. Monoid m => Exp m -> m
fold :: forall m. Monoid m => Exp m -> m
$cfoldMap :: forall m a. Monoid m => (a -> m) -> Exp a -> m
foldMap :: forall m a. Monoid m => (a -> m) -> Exp a -> m
$cfoldMap' :: forall m a. Monoid m => (a -> m) -> Exp a -> m
foldMap' :: forall m a. Monoid m => (a -> m) -> Exp a -> m
$cfoldr :: forall a b. (a -> b -> b) -> b -> Exp a -> b
foldr :: forall a b. (a -> b -> b) -> b -> Exp a -> b
$cfoldr' :: forall a b. (a -> b -> b) -> b -> Exp a -> b
foldr' :: forall a b. (a -> b -> b) -> b -> Exp a -> b
$cfoldl :: forall b a. (b -> a -> b) -> b -> Exp a -> b
foldl :: forall b a. (b -> a -> b) -> b -> Exp a -> b
$cfoldl' :: forall b a. (b -> a -> b) -> b -> Exp a -> b
foldl' :: forall b a. (b -> a -> b) -> b -> Exp a -> b
$cfoldr1 :: forall a. (a -> a -> a) -> Exp a -> a
foldr1 :: forall a. (a -> a -> a) -> Exp a -> a
$cfoldl1 :: forall a. (a -> a -> a) -> Exp a -> a
foldl1 :: forall a. (a -> a -> a) -> Exp a -> a
$ctoList :: forall a. Exp a -> [a]
toList :: forall a. Exp a -> [a]
$cnull :: forall a. Exp a -> Bool
null :: forall a. Exp a -> Bool
$clength :: forall a. Exp a -> Int
length :: forall a. Exp a -> Int
$celem :: forall a. Eq a => a -> Exp a -> Bool
elem :: forall a. Eq a => a -> Exp a -> Bool
$cmaximum :: forall a. Ord a => Exp a -> a
maximum :: forall a. Ord a => Exp a -> a
$cminimum :: forall a. Ord a => Exp a -> a
minimum :: forall a. Ord a => Exp a -> a
$csum :: forall a. Num a => Exp a -> a
sum :: forall a. Num a => Exp a -> a
$cproduct :: forall a. Num a => Exp a -> a
product :: forall a. Num a => Exp a -> a
Foldable,Functor Exp
Foldable Exp
(Functor Exp, Foldable Exp) =>
(forall (f :: * -> *) a b.
 Applicative f =>
 (a -> f b) -> Exp a -> f (Exp b))
-> (forall (f :: * -> *) a.
    Applicative f =>
    Exp (f a) -> f (Exp a))
-> (forall (m :: * -> *) a b.
    Monad m =>
    (a -> m b) -> Exp a -> m (Exp b))
-> (forall (m :: * -> *) a. Monad m => Exp (m a) -> m (Exp a))
-> Traversable Exp
forall (t :: * -> *).
(Functor t, Foldable t) =>
(forall (f :: * -> *) a b.
 Applicative f =>
 (a -> f b) -> t a -> f (t b))
-> (forall (f :: * -> *) a. Applicative f => t (f a) -> f (t a))
-> (forall (m :: * -> *) a b.
    Monad m =>
    (a -> m b) -> t a -> m (t b))
-> (forall (m :: * -> *) a. Monad m => t (m a) -> m (t a))
-> Traversable t
forall (m :: * -> *) a. Monad m => Exp (m a) -> m (Exp a)
forall (f :: * -> *) a. Applicative f => Exp (f a) -> f (Exp a)
forall (m :: * -> *) a b.
Monad m =>
(a -> m b) -> Exp a -> m (Exp b)
forall (f :: * -> *) a b.
Applicative f =>
(a -> f b) -> Exp a -> f (Exp b)
$ctraverse :: forall (f :: * -> *) a b.
Applicative f =>
(a -> f b) -> Exp a -> f (Exp b)
traverse :: forall (f :: * -> *) a b.
Applicative f =>
(a -> f b) -> Exp a -> f (Exp b)
$csequenceA :: forall (f :: * -> *) a. Applicative f => Exp (f a) -> f (Exp a)
sequenceA :: forall (f :: * -> *) a. Applicative f => Exp (f a) -> f (Exp a)
$cmapM :: forall (m :: * -> *) a b.
Monad m =>
(a -> m b) -> Exp a -> m (Exp b)
mapM :: forall (m :: * -> *) a b.
Monad m =>
(a -> m b) -> Exp a -> m (Exp b)
$csequence :: forall (m :: * -> *) a. Monad m => Exp (m a) -> m (Exp a)
sequence :: forall (m :: * -> *) a. Monad m => Exp (m a) -> m (Exp a)
Traversable,(forall a b. (a -> b) -> Exp a -> Exp b)
-> (forall a b. a -> Exp b -> Exp a) -> Functor Exp
forall a b. a -> Exp b -> Exp a
forall a b. (a -> b) -> Exp a -> Exp b
forall (f :: * -> *).
(forall a b. (a -> b) -> f a -> f b)
-> (forall a b. a -> f b -> f a) -> Functor f
$cfmap :: forall a b. (a -> b) -> Exp a -> Exp b
fmap :: forall a b. (a -> b) -> Exp a -> Exp b
$c<$ :: forall a b. a -> Exp b -> Exp a
<$ :: forall a b. a -> Exp b -> Exp a
Functor)

fromExp :: Exp a -> a
fromExp :: forall a. Exp a -> a
fromExp (Exp a
x) = a
x

instance Additive a => Multiplicative (Exp a) where
  Exp a
a * :: Exp a -> Exp a -> Exp a
* Exp a
b = a -> Exp a
forall a. a -> Exp a
Exp (a
a a -> a -> a
forall a. Additive a => a -> a -> a
+ a
b)
  one :: Exp a
one = a -> Exp a
forall a. a -> Exp a
Exp a
forall a. Additive a => a
zero
  Exp a
a ^+ :: Exp a -> Natural -> Exp a
^+ Natural
n = a -> Exp a
forall a. a -> Exp a
Exp (Natural -> a -> a
forall a. Additive a => Natural -> a -> a
times Natural
n a
a)

instance Group a => Division (Exp a) where
  recip :: Exp a -> Exp a
recip (Exp a
a) = a -> Exp a
forall a. a -> Exp a
Exp (a -> a
forall a. Group a => a -> a
negate a
a)
  Exp a
a / :: Exp a -> Exp a -> Exp a
/ Exp a
b = a -> Exp a
forall a. a -> Exp a
Exp (a
a a -> a -> a
forall a. Group a => a -> a -> a
- a
b)

instance Field a => Roots (Exp a) where
  root :: Natural -> Exp a -> Exp a
root Natural
n (Exp a
x) = a -> Exp a
forall a. a -> Exp a
Exp (a
x a -> a -> a
forall a. Division a => a -> a -> a
/ Natural -> a
forall a. Ring a => Natural -> a
fromInteger Natural
n)


newtype Log a = Log a deriving (Int -> Log a -> ShowS
[Log a] -> ShowS
Log a -> String
(Int -> Log a -> ShowS)
-> (Log a -> String) -> ([Log a] -> ShowS) -> Show (Log a)
forall a. Show a => Int -> Log a -> ShowS
forall a. Show a => [Log a] -> ShowS
forall a. Show a => Log a -> String
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: forall a. Show a => Int -> Log a -> ShowS
showsPrec :: Int -> Log a -> ShowS
$cshow :: forall a. Show a => Log a -> String
show :: Log a -> String
$cshowList :: forall a. Show a => [Log a] -> ShowS
showList :: [Log a] -> ShowS
Show,Log a -> Log a -> Bool
(Log a -> Log a -> Bool) -> (Log a -> Log a -> Bool) -> Eq (Log a)
forall a. Eq a => Log a -> Log a -> Bool
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: forall a. Eq a => Log a -> Log a -> Bool
== :: Log a -> Log a -> Bool
$c/= :: forall a. Eq a => Log a -> Log a -> Bool
/= :: Log a -> Log a -> Bool
Eq,Eq (Log a)
Eq (Log a) =>
(Log a -> Log a -> Ordering)
-> (Log a -> Log a -> Bool)
-> (Log a -> Log a -> Bool)
-> (Log a -> Log a -> Bool)
-> (Log a -> Log a -> Bool)
-> (Log a -> Log a -> Log a)
-> (Log a -> Log a -> Log a)
-> Ord (Log a)
Log a -> Log a -> Bool
Log a -> Log a -> Ordering
Log a -> Log a -> Log a
forall a.
Eq a =>
(a -> a -> Ordering)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> a)
-> (a -> a -> a)
-> Ord a
forall a. Ord a => Eq (Log a)
forall a. Ord a => Log a -> Log a -> Bool
forall a. Ord a => Log a -> Log a -> Ordering
forall a. Ord a => Log a -> Log a -> Log a
$ccompare :: forall a. Ord a => Log a -> Log a -> Ordering
compare :: Log a -> Log a -> Ordering
$c< :: forall a. Ord a => Log a -> Log a -> Bool
< :: Log a -> Log a -> Bool
$c<= :: forall a. Ord a => Log a -> Log a -> Bool
<= :: Log a -> Log a -> Bool
$c> :: forall a. Ord a => Log a -> Log a -> Bool
> :: Log a -> Log a -> Bool
$c>= :: forall a. Ord a => Log a -> Log a -> Bool
>= :: Log a -> Log a -> Bool
$cmax :: forall a. Ord a => Log a -> Log a -> Log a
max :: Log a -> Log a -> Log a
$cmin :: forall a. Ord a => Log a -> Log a -> Log a
min :: Log a -> Log a -> Log a
Ord)

fromLog :: Log a -> a
fromLog :: forall a. Log a -> a
fromLog (Log a
x) = a
x

instance Multiplicative a => Additive (Log a) where
  Log a
a + :: Log a -> Log a -> Log a
+ Log a
b = a -> Log a
forall a. a -> Log a
Log (a
a a -> a -> a
forall a. Multiplicative a => a -> a -> a
* a
b)
  zero :: Log a
zero = a -> Log a
forall a. a -> Log a
Log a
forall a. Multiplicative a => a
one
  times :: Natural -> Log a -> Log a
times Natural
n (Log a
a) = a -> Log a
forall a. a -> Log a
Log (a
a a -> Natural -> a
forall a. Multiplicative a => a -> Natural -> a
^+ Natural
n)

instance Multiplicative a => Scalable Integer (Log a) where
  Natural
n *^ :: Natural -> Log a -> Log a
*^ Log a
x = a -> Log a
forall a. a -> Log a
Log (a
x a -> Natural -> a
forall a. Multiplicative a => a -> Natural -> a
^+ Natural
n)
  
instance Division a => Group (Log a) where
  negate :: Log a -> Log a
negate (Log a
a) = a -> Log a
forall a. a -> Log a
Log (a -> a
forall a. Division a => a -> a
recip a
a)
  Log a
a - :: Log a -> Log a -> Log a
- Log a
b = a -> Log a
forall a. a -> Log a
Log (a
a a -> a -> a
forall a. Division a => a -> a -> a
/ a
b)

-- instance Roots a => Field (Log a) where
-- fromRational x = Log (root (denominator x) (fromInteger (numerator x)))