{-# LANGUAGE UndecidableInstances #-}
{-# OPTIONS_GHC -fno-warn-orphans #-}

-- | Module    :  NumHask.Extra
-- Copyright   :  (C) 2023 Alexey Tochin
-- License     :  BSD3 (see the file LICENSE)
-- Maintainer  :  Alexey Tochin <Alexey.Tochin@gmail.com>
--
-- Additional orphan instances for
-- [mumhusk](https://hackage.haskell.org/package/numhask)
-- typeclasses.
module NumHask.Extra () where

import NumHask (Additive, zero, (+))
import Prelude hiding (Num, (+))

instance {-# INCOHERENT #-} Additive () where
  + :: () -> () -> ()
(+) = forall a b. a -> b -> a
const
  zero :: ()
zero = ()

instance {-# INCOHERENT #-} (Additive x, Additive y) => Additive (x, y) where
  zero :: (x, y)
zero = (forall a. Additive a => a
zero, forall a. Additive a => a
zero)
  (x
a, y
b) + :: (x, y) -> (x, y) -> (x, y)
+ (x
c, y
d) = (x
a forall a. Additive a => a -> a -> a
+ x
c, y
b forall a. Additive a => a -> a -> a
+ y
d)

instance {-# INCOHERENT #-} (Additive x, Additive y, Additive z) => Additive (x, y, z) where
  zero :: (x, y, z)
zero = (forall a. Additive a => a
zero, forall a. Additive a => a
zero, forall a. Additive a => a
zero)
  (x
x1, y
y1, z
z1) + :: (x, y, z) -> (x, y, z) -> (x, y, z)
+ (x
x2, y
y2, z
z2) = (x
x1 forall a. Additive a => a -> a -> a
+ x
x2, y
y1 forall a. Additive a => a -> a -> a
+ y
y2, z
z1 forall a. Additive a => a -> a -> a
+ z
z2)

instance {-# INCOHERENT #-} (Additive x, Additive y, Additive z, Additive t) => Additive (x, y, z, t) where
  zero :: (x, y, z, t)
zero = (forall a. Additive a => a
zero, forall a. Additive a => a
zero, forall a. Additive a => a
zero, forall a. Additive a => a
zero)
  (x
x1, y
y1, z
z1, t
t1) + :: (x, y, z, t) -> (x, y, z, t) -> (x, y, z, t)
+ (x
x2, y
y2, z
z2, t
t2) = (x
x1 forall a. Additive a => a -> a -> a
+ x
x2, y
y1 forall a. Additive a => a -> a -> a
+ y
y2, z
z1 forall a. Additive a => a -> a -> a
+ z
z2, t
t1 forall a. Additive a => a -> a -> a
+ t
t2)

instance
  {-# INCOHERENT #-}
  (Additive x, Additive y, Additive z, Additive t, Additive s) =>
  Additive (x, y, z, t, s)
  where
  zero :: (x, y, z, t, s)
zero = (forall a. Additive a => a
zero, forall a. Additive a => a
zero, forall a. Additive a => a
zero, forall a. Additive a => a
zero, forall a. Additive a => a
zero)
  (x
x1, y
y1, z
z1, t
t1, s
s1) + :: (x, y, z, t, s) -> (x, y, z, t, s) -> (x, y, z, t, s)
+ (x
x2, y
y2, z
z2, t
t2, s
s2) = (x
x1 forall a. Additive a => a -> a -> a
+ x
x2, y
y1 forall a. Additive a => a -> a -> a
+ y
y2, z
z1 forall a. Additive a => a -> a -> a
+ z
z2, t
t1 forall a. Additive a => a -> a -> a
+ t
t2, s
s1 forall a. Additive a => a -> a -> a
+ s
s2)