{-# LANGUAGE FunctionalDependencies #-}

{- | The typeclasses provides in this module are equivalent
     to three of the typeclasses from the @vector-space@
     package. This package uses MPTCs with functional dependencies
     instead of type families in order to improved error
     messages.
-}
module Torsor
  ( Additive (..)
  , Torsor (..)
  , Scaling (..)
  ) where

import Data.Int
import Data.Word

class Additive v where
  zero :: v
  invert :: v -> v
  plus :: v -> v -> v
  minus :: v -> v -> v

class (Additive v) => Torsor p v | p -> v where
  add :: v -> p -> p
  difference :: p -> p -> v

class (Additive v, Additive s) => Scaling v s | v -> s where
  scale :: s -> v -> v

instance Additive Int where
  zero :: Int
zero = Int
0
  invert :: Int -> Int
invert = Int -> Int
forall a. Num a => a -> a
negate
  plus :: Int -> Int -> Int
plus = Int -> Int -> Int
forall a. Num a => a -> a -> a
(+)
  minus :: Int -> Int -> Int
minus = (-)

instance Torsor Int Int where
  add :: Int -> Int -> Int
add = Int -> Int -> Int
forall a. Num a => a -> a -> a
(+)
  difference :: Int -> Int -> Int
difference = (-)

instance Scaling Int Int where
  scale :: Int -> Int -> Int
scale = Int -> Int -> Int
forall a. Num a => a -> a -> a
(*)

instance Additive Word where
  zero :: Word
zero = Word
0
  invert :: Word -> Word
invert = Word -> Word
forall a. Num a => a -> a
negate
  plus :: Word -> Word -> Word
plus = Word -> Word -> Word
forall a. Num a => a -> a -> a
(+)
  minus :: Word -> Word -> Word
minus = (-)

instance Torsor Word Word where
  add :: Word -> Word -> Word
add = Word -> Word -> Word
forall a. Num a => a -> a -> a
(+)
  difference :: Word -> Word -> Word
difference = (-)

instance Scaling Word Word where
  scale :: Word -> Word -> Word
scale = Word -> Word -> Word
forall a. Num a => a -> a -> a
(*)

instance Additive Double where
  zero :: Double
zero = Double
0
  invert :: Double -> Double
invert = Double -> Double
forall a. Num a => a -> a
negate
  plus :: Double -> Double -> Double
plus = Double -> Double -> Double
forall a. Num a => a -> a -> a
(+)
  minus :: Double -> Double -> Double
minus = (-)

instance Torsor Double Double where
  add :: Double -> Double -> Double
add = Double -> Double -> Double
forall a. Num a => a -> a -> a
(+)
  difference :: Double -> Double -> Double
difference = (-)

instance Scaling Double Double where
  scale :: Double -> Double -> Double
scale = Double -> Double -> Double
forall a. Num a => a -> a -> a
(*)

instance Additive Int64 where
  zero :: Int64
zero = Int64
0
  invert :: Int64 -> Int64
invert = Int64 -> Int64
forall a. Num a => a -> a
negate
  plus :: Int64 -> Int64 -> Int64
plus = Int64 -> Int64 -> Int64
forall a. Num a => a -> a -> a
(+)
  minus :: Int64 -> Int64 -> Int64
minus = (-)

instance Torsor Int64 Int64 where
  add :: Int64 -> Int64 -> Int64
add = Int64 -> Int64 -> Int64
forall a. Num a => a -> a -> a
(+)
  difference :: Int64 -> Int64 -> Int64
difference = (-)

instance Scaling Int64 Int64 where
  scale :: Int64 -> Int64 -> Int64
scale = Int64 -> Int64 -> Int64
forall a. Num a => a -> a -> a
(*)

instance Additive Word64 where
  zero :: Word64
zero = Word64
0
  invert :: Word64 -> Word64
invert = Word64 -> Word64
forall a. Num a => a -> a
negate
  plus :: Word64 -> Word64 -> Word64
plus = Word64 -> Word64 -> Word64
forall a. Num a => a -> a -> a
(+)
  minus :: Word64 -> Word64 -> Word64
minus = (-)

instance Torsor Word64 Word64 where
  add :: Word64 -> Word64 -> Word64
add = Word64 -> Word64 -> Word64
forall a. Num a => a -> a -> a
(+)
  difference :: Word64 -> Word64 -> Word64
difference = (-)

instance Scaling Word64 Word64 where
  scale :: Word64 -> Word64 -> Word64
scale = Word64 -> Word64 -> Word64
forall a. Num a => a -> a -> a
(*)

instance Additive Word32 where
  zero :: Word32
zero = Word32
0
  invert :: Word32 -> Word32
invert = Word32 -> Word32
forall a. Num a => a -> a
negate
  plus :: Word32 -> Word32 -> Word32
plus = Word32 -> Word32 -> Word32
forall a. Num a => a -> a -> a
(+)
  minus :: Word32 -> Word32 -> Word32
minus = (-)

instance Torsor Word32 Word32 where
  add :: Word32 -> Word32 -> Word32
add = Word32 -> Word32 -> Word32
forall a. Num a => a -> a -> a
(+)
  difference :: Word32 -> Word32 -> Word32
difference = (-)

instance Scaling Word32 Word32 where
  scale :: Word32 -> Word32 -> Word32
scale = Word32 -> Word32 -> Word32
forall a. Num a => a -> a -> a
(*)

instance Additive Word16 where
  zero :: Word16
zero = Word16
0
  invert :: Word16 -> Word16
invert = Word16 -> Word16
forall a. Num a => a -> a
negate
  plus :: Word16 -> Word16 -> Word16
plus = Word16 -> Word16 -> Word16
forall a. Num a => a -> a -> a
(+)
  minus :: Word16 -> Word16 -> Word16
minus = (-)

instance Torsor Word16 Word16 where
  add :: Word16 -> Word16 -> Word16
add = Word16 -> Word16 -> Word16
forall a. Num a => a -> a -> a
(+)
  difference :: Word16 -> Word16 -> Word16
difference = (-)

instance Scaling Word16 Word16 where
  scale :: Word16 -> Word16 -> Word16
scale = Word16 -> Word16 -> Word16
forall a. Num a => a -> a -> a
(*)

instance Additive Word8 where
  zero :: Word8
zero = Word8
0
  invert :: Word8 -> Word8
invert = Word8 -> Word8
forall a. Num a => a -> a
negate
  plus :: Word8 -> Word8 -> Word8
plus = Word8 -> Word8 -> Word8
forall a. Num a => a -> a -> a
(+)
  minus :: Word8 -> Word8 -> Word8
minus = (-)

instance Torsor Word8 Word8 where
  add :: Word8 -> Word8 -> Word8
add = Word8 -> Word8 -> Word8
forall a. Num a => a -> a -> a
(+)
  difference :: Word8 -> Word8 -> Word8
difference = (-)

instance Scaling Word8 Word8 where
  scale :: Word8 -> Word8 -> Word8
scale = Word8 -> Word8 -> Word8
forall a. Num a => a -> a -> a
(*)

instance Additive Int32 where
  zero :: Int32
zero = Int32
0
  invert :: Int32 -> Int32
invert = Int32 -> Int32
forall a. Num a => a -> a
negate
  plus :: Int32 -> Int32 -> Int32
plus = Int32 -> Int32 -> Int32
forall a. Num a => a -> a -> a
(+)
  minus :: Int32 -> Int32 -> Int32
minus = (-)

instance Torsor Int32 Int32 where
  add :: Int32 -> Int32 -> Int32
add = Int32 -> Int32 -> Int32
forall a. Num a => a -> a -> a
(+)
  difference :: Int32 -> Int32 -> Int32
difference = (-)

instance Scaling Int32 Int32 where
  scale :: Int32 -> Int32 -> Int32
scale = Int32 -> Int32 -> Int32
forall a. Num a => a -> a -> a
(*)

instance Additive Int16 where
  zero :: Int16
zero = Int16
0
  invert :: Int16 -> Int16
invert = Int16 -> Int16
forall a. Num a => a -> a
negate
  plus :: Int16 -> Int16 -> Int16
plus = Int16 -> Int16 -> Int16
forall a. Num a => a -> a -> a
(+)
  minus :: Int16 -> Int16 -> Int16
minus = (-)

instance Torsor Int16 Int16 where
  add :: Int16 -> Int16 -> Int16
add = Int16 -> Int16 -> Int16
forall a. Num a => a -> a -> a
(+)
  difference :: Int16 -> Int16 -> Int16
difference = (-)

instance Scaling Int16 Int16 where
  scale :: Int16 -> Int16 -> Int16
scale = Int16 -> Int16 -> Int16
forall a. Num a => a -> a -> a
(*)

instance Additive Int8 where
  zero :: Int8
zero = Int8
0
  invert :: Int8 -> Int8
invert = Int8 -> Int8
forall a. Num a => a -> a
negate
  plus :: Int8 -> Int8 -> Int8
plus = Int8 -> Int8 -> Int8
forall a. Num a => a -> a -> a
(+)
  minus :: Int8 -> Int8 -> Int8
minus = (-)

instance Torsor Int8 Int8 where
  add :: Int8 -> Int8 -> Int8
add = Int8 -> Int8 -> Int8
forall a. Num a => a -> a -> a
(+)
  difference :: Int8 -> Int8 -> Int8
difference = (-)

instance Scaling Int8 Int8 where
  scale :: Int8 -> Int8 -> Int8
scale = Int8 -> Int8 -> Int8
forall a. Num a => a -> a -> a
(*)