{-# LANGUAGE ConstraintKinds #-}
{-# LANGUAGE FlexibleContexts #-}
{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE MultiParamTypeClasses #-}
{-# LANGUAGE RebindableSyntax #-}
{-# LANGUAGE TypeFamilies #-}
{-# OPTIONS_GHC -Wall #-}

-- | Integral classes
module NumHask.Data.Integral
  ( Integral (..),
    ToIntegral (..),
    FromIntegral (..),
    FromInteger (..),
    even,
    odd,
    (^^),
    (^),
  )
where

import Data.Int (Int16, Int32, Int64, Int8)
import Data.Ord
import Data.Word (Word, Word16, Word32, Word64, Word8)
import GHC.Natural (Natural (..), naturalFromInteger)
import NumHask.Algebra.Additive
import NumHask.Algebra.Multiplicative
import NumHask.Algebra.Ring
import Prelude (Double, Float, Int, Integer, fst, snd, (.))
import qualified Prelude as P

-- $setup
--
-- >>> :set -XRebindableSyntax
-- >>> import NumHask.Prelude

-- | An Integral is anything that satisfies the law:
--
-- prop> \a b -> b == zero || b * (a `div` b) + (a `mod` b) == a
--
-- >>> 3 `divMod` 2
-- (1,1)
--
-- >>> (-3) `divMod` 2
-- (-2,1)
--
-- >>> (-3) `quotRem` 2
-- (-1,-1)
class
  (Distributive a) =>
  Integral a
  where
  infixl 7 `div`, `mod`
  div :: a -> a -> a
  div a
a1 a
a2 = forall a b. (a, b) -> a
fst (forall a. Integral a => a -> a -> (a, a)
divMod a
a1 a
a2)
  mod :: a -> a -> a
  mod a
a1 a
a2 = forall a b. (a, b) -> b
snd (forall a. Integral a => a -> a -> (a, a)
divMod a
a1 a
a2)

  divMod :: a -> a -> (a, a)

  quot :: a -> a -> a
  quot a
a1 a
a2 = forall a b. (a, b) -> a
fst (forall a. Integral a => a -> a -> (a, a)
quotRem a
a1 a
a2)
  rem :: a -> a -> a
  rem a
a1 a
a2 = forall a b. (a, b) -> b
snd (forall a. Integral a => a -> a -> (a, a)
quotRem a
a1 a
a2)

  quotRem :: a -> a -> (a, a)

instance Integral Int where
  divMod :: Int -> Int -> (Int, Int)
divMod = forall a. Integral a => a -> a -> (a, a)
P.divMod
  quotRem :: Int -> Int -> (Int, Int)
quotRem = forall a. Integral a => a -> a -> (a, a)
P.quotRem

instance Integral Integer where
  divMod :: Integer -> Integer -> (Integer, Integer)
divMod = forall a. Integral a => a -> a -> (a, a)
P.divMod
  quotRem :: Integer -> Integer -> (Integer, Integer)
quotRem = forall a. Integral a => a -> a -> (a, a)
P.quotRem

instance Integral Natural where
  divMod :: Natural -> Natural -> (Natural, Natural)
divMod = forall a. Integral a => a -> a -> (a, a)
P.divMod
  quotRem :: Natural -> Natural -> (Natural, Natural)
quotRem = forall a. Integral a => a -> a -> (a, a)
P.quotRem

instance Integral Int8 where
  divMod :: Int8 -> Int8 -> (Int8, Int8)
divMod = forall a. Integral a => a -> a -> (a, a)
P.divMod
  quotRem :: Int8 -> Int8 -> (Int8, Int8)
quotRem = forall a. Integral a => a -> a -> (a, a)
P.quotRem

instance Integral Int16 where
  divMod :: Int16 -> Int16 -> (Int16, Int16)
divMod = forall a. Integral a => a -> a -> (a, a)
P.divMod
  quotRem :: Int16 -> Int16 -> (Int16, Int16)
quotRem = forall a. Integral a => a -> a -> (a, a)
P.quotRem

instance Integral Int32 where
  divMod :: Int32 -> Int32 -> (Int32, Int32)
divMod = forall a. Integral a => a -> a -> (a, a)
P.divMod
  quotRem :: Int32 -> Int32 -> (Int32, Int32)
quotRem = forall a. Integral a => a -> a -> (a, a)
P.quotRem

instance Integral Int64 where
  divMod :: Int64 -> Int64 -> (Int64, Int64)
divMod = forall a. Integral a => a -> a -> (a, a)
P.divMod
  quotRem :: Int64 -> Int64 -> (Int64, Int64)
quotRem = forall a. Integral a => a -> a -> (a, a)
P.quotRem

instance Integral Word where
  divMod :: Word -> Word -> (Word, Word)
divMod = forall a. Integral a => a -> a -> (a, a)
P.divMod
  quotRem :: Word -> Word -> (Word, Word)
quotRem = forall a. Integral a => a -> a -> (a, a)
P.quotRem

instance Integral Word8 where
  divMod :: Word8 -> Word8 -> (Word8, Word8)
divMod = forall a. Integral a => a -> a -> (a, a)
P.divMod
  quotRem :: Word8 -> Word8 -> (Word8, Word8)
quotRem = forall a. Integral a => a -> a -> (a, a)
P.quotRem

instance Integral Word16 where
  divMod :: Word16 -> Word16 -> (Word16, Word16)
divMod = forall a. Integral a => a -> a -> (a, a)
P.divMod
  quotRem :: Word16 -> Word16 -> (Word16, Word16)
quotRem = forall a. Integral a => a -> a -> (a, a)
P.quotRem

instance Integral Word32 where
  divMod :: Word32 -> Word32 -> (Word32, Word32)
divMod = forall a. Integral a => a -> a -> (a, a)
P.divMod
  quotRem :: Word32 -> Word32 -> (Word32, Word32)
quotRem = forall a. Integral a => a -> a -> (a, a)
P.quotRem

instance Integral Word64 where
  divMod :: Word64 -> Word64 -> (Word64, Word64)
divMod = forall a. Integral a => a -> a -> (a, a)
P.divMod
  quotRem :: Word64 -> Word64 -> (Word64, Word64)
quotRem = forall a. Integral a => a -> a -> (a, a)
P.quotRem

instance (Integral b) => Integral (a -> b) where
  div :: (a -> b) -> (a -> b) -> a -> b
div a -> b
f a -> b
f' a
a = a -> b
f a
a forall a. Integral a => a -> a -> a
`div` a -> b
f' a
a
  mod :: (a -> b) -> (a -> b) -> a -> b
mod a -> b
f a -> b
f' a
a = a -> b
f a
a forall a. Integral a => a -> a -> a
`mod` a -> b
f' a
a
  divMod :: (a -> b) -> (a -> b) -> (a -> b, a -> b)
divMod a -> b
f a -> b
f' = (\a
a -> forall a b. (a, b) -> a
fst (a -> b
f a
a forall a. Integral a => a -> a -> (a, a)
`divMod` a -> b
f' a
a), \a
a -> forall a b. (a, b) -> b
snd (a -> b
f a
a forall a. Integral a => a -> a -> (a, a)
`divMod` a -> b
f' a
a))
  quot :: (a -> b) -> (a -> b) -> a -> b
quot a -> b
f a -> b
f' a
a = a -> b
f a
a forall a. Integral a => a -> a -> a
`mod` a -> b
f' a
a
  rem :: (a -> b) -> (a -> b) -> a -> b
rem a -> b
f a -> b
f' a
a = a -> b
f a
a forall a. Integral a => a -> a -> a
`mod` a -> b
f' a
a
  quotRem :: (a -> b) -> (a -> b) -> (a -> b, a -> b)
quotRem a -> b
f a -> b
f' = (\a
a -> forall a b. (a, b) -> a
fst (a -> b
f a
a forall a. Integral a => a -> a -> (a, a)
`quotRem` a -> b
f' a
a), \a
a -> forall a b. (a, b) -> b
snd (a -> b
f a
a forall a. Integral a => a -> a -> (a, a)
`quotRem` a -> b
f' a
a))

-- | toIntegral is kept separate from Integral to help with compatability issues.
--
-- > toIntegral a == a
class ToIntegral a b where
  {-# MINIMAL toIntegral #-}

  toIntegral :: a -> b

instance ToIntegral Integer Integer where
  toIntegral :: Integer -> Integer
toIntegral = forall a. a -> a
P.id

instance ToIntegral Int Integer where
  toIntegral :: Int -> Integer
toIntegral = forall a. Integral a => a -> Integer
P.toInteger

instance ToIntegral Natural Integer where
  toIntegral :: Natural -> Integer
toIntegral = forall a. Integral a => a -> Integer
P.toInteger

instance ToIntegral Int8 Integer where
  toIntegral :: Int8 -> Integer
toIntegral = forall a. Integral a => a -> Integer
P.toInteger

instance ToIntegral Int16 Integer where
  toIntegral :: Int16 -> Integer
toIntegral = forall a. Integral a => a -> Integer
P.toInteger

instance ToIntegral Int32 Integer where
  toIntegral :: Int32 -> Integer
toIntegral = forall a. Integral a => a -> Integer
P.toInteger

instance ToIntegral Int64 Integer where
  toIntegral :: Int64 -> Integer
toIntegral = forall a. Integral a => a -> Integer
P.toInteger

instance ToIntegral Word Integer where
  toIntegral :: Word -> Integer
toIntegral = forall a. Integral a => a -> Integer
P.toInteger

instance ToIntegral Word8 Integer where
  toIntegral :: Word8 -> Integer
toIntegral = forall a. Integral a => a -> Integer
P.toInteger

instance ToIntegral Word16 Integer where
  toIntegral :: Word16 -> Integer
toIntegral = forall a. Integral a => a -> Integer
P.toInteger

instance ToIntegral Word32 Integer where
  toIntegral :: Word32 -> Integer
toIntegral = forall a. Integral a => a -> Integer
P.toInteger

instance ToIntegral Word64 Integer where
  toIntegral :: Word64 -> Integer
toIntegral = forall a. Integral a => a -> Integer
P.toInteger

instance ToIntegral Int Int where
  toIntegral :: Int -> Int
toIntegral = forall a. a -> a
P.id

instance ToIntegral Integer Int where
  toIntegral :: Integer -> Int
toIntegral = forall a b. (Integral a, Num b) => a -> b
P.fromIntegral

instance ToIntegral Natural Int where
  toIntegral :: Natural -> Int
toIntegral = forall a b. (Integral a, Num b) => a -> b
P.fromIntegral

instance ToIntegral Int8 Int where
  toIntegral :: Int8 -> Int
toIntegral = forall a b. (Integral a, Num b) => a -> b
P.fromIntegral

instance ToIntegral Int16 Int where
  toIntegral :: Int16 -> Int
toIntegral = forall a b. (Integral a, Num b) => a -> b
P.fromIntegral

instance ToIntegral Int32 Int where
  toIntegral :: Int32 -> Int
toIntegral = forall a b. (Integral a, Num b) => a -> b
P.fromIntegral

instance ToIntegral Int64 Int where
  toIntegral :: Int64 -> Int
toIntegral = forall a b. (Integral a, Num b) => a -> b
P.fromIntegral

instance ToIntegral Word Int where
  toIntegral :: Word -> Int
toIntegral = forall a b. (Integral a, Num b) => a -> b
P.fromIntegral

instance ToIntegral Word8 Int where
  toIntegral :: Word8 -> Int
toIntegral = forall a b. (Integral a, Num b) => a -> b
P.fromIntegral

instance ToIntegral Word16 Int where
  toIntegral :: Word16 -> Int
toIntegral = forall a b. (Integral a, Num b) => a -> b
P.fromIntegral

instance ToIntegral Word32 Int where
  toIntegral :: Word32 -> Int
toIntegral = forall a b. (Integral a, Num b) => a -> b
P.fromIntegral

instance ToIntegral Word64 Int where
  toIntegral :: Word64 -> Int
toIntegral = forall a b. (Integral a, Num b) => a -> b
P.fromIntegral

instance ToIntegral Natural Natural where
  toIntegral :: Natural -> Natural
toIntegral = forall a. a -> a
P.id

instance ToIntegral Int8 Int8 where
  toIntegral :: Int8 -> Int8
toIntegral = forall a. a -> a
P.id

instance ToIntegral Int16 Int16 where
  toIntegral :: Int16 -> Int16
toIntegral = forall a. a -> a
P.id

instance ToIntegral Int32 Int32 where
  toIntegral :: Int32 -> Int32
toIntegral = forall a. a -> a
P.id

instance ToIntegral Int64 Int64 where
  toIntegral :: Int64 -> Int64
toIntegral = forall a. a -> a
P.id

instance ToIntegral Word Word where
  toIntegral :: Word -> Word
toIntegral = forall a. a -> a
P.id

instance ToIntegral Word8 Word8 where
  toIntegral :: Word8 -> Word8
toIntegral = forall a. a -> a
P.id

instance ToIntegral Word16 Word16 where
  toIntegral :: Word16 -> Word16
toIntegral = forall a. a -> a
P.id

instance ToIntegral Word32 Word32 where
  toIntegral :: Word32 -> Word32
toIntegral = forall a. a -> a
P.id

instance ToIntegral Word64 Word64 where
  toIntegral :: Word64 -> Word64
toIntegral = forall a. a -> a
P.id

-- | Polymorphic version of fromInteger
--
-- > fromIntegral a == a
class FromIntegral a b where
  {-# MINIMAL fromIntegral #-}

  fromIntegral :: b -> a

instance (FromIntegral a b) => FromIntegral (c -> a) b where
  fromIntegral :: b -> c -> a
fromIntegral b
i c
_ = forall a b. FromIntegral a b => b -> a
fromIntegral b
i

instance FromIntegral Double Integer where
  fromIntegral :: Integer -> Double
fromIntegral = forall a. Num a => Integer -> a
P.fromInteger

instance FromIntegral Float Integer where
  fromIntegral :: Integer -> Float
fromIntegral = forall a. Num a => Integer -> a
P.fromInteger

instance FromIntegral Int Integer where
  fromIntegral :: Integer -> Int
fromIntegral = forall a. Num a => Integer -> a
P.fromInteger

instance FromIntegral Integer Integer where
  fromIntegral :: Integer -> Integer
fromIntegral = forall a. a -> a
P.id

instance FromIntegral Natural Integer where
  fromIntegral :: Integer -> Natural
fromIntegral = Integer -> Natural
naturalFromInteger

instance FromIntegral Int8 Integer where
  fromIntegral :: Integer -> Int8
fromIntegral = forall a. Num a => Integer -> a
P.fromInteger

instance FromIntegral Int16 Integer where
  fromIntegral :: Integer -> Int16
fromIntegral = forall a. Num a => Integer -> a
P.fromInteger

instance FromIntegral Int32 Integer where
  fromIntegral :: Integer -> Int32
fromIntegral = forall a. Num a => Integer -> a
P.fromInteger

instance FromIntegral Int64 Integer where
  fromIntegral :: Integer -> Int64
fromIntegral = forall a. Num a => Integer -> a
P.fromInteger

instance FromIntegral Word Integer where
  fromIntegral :: Integer -> Word
fromIntegral = forall a. Num a => Integer -> a
P.fromInteger

instance FromIntegral Word8 Integer where
  fromIntegral :: Integer -> Word8
fromIntegral = forall a. Num a => Integer -> a
P.fromInteger

instance FromIntegral Word16 Integer where
  fromIntegral :: Integer -> Word16
fromIntegral = forall a. Num a => Integer -> a
P.fromInteger

instance FromIntegral Word32 Integer where
  fromIntegral :: Integer -> Word32
fromIntegral = forall a. Num a => Integer -> a
P.fromInteger

instance FromIntegral Word64 Integer where
  fromIntegral :: Integer -> Word64
fromIntegral = forall a. Num a => Integer -> a
P.fromInteger

instance FromIntegral Double Int where
  fromIntegral :: Int -> Double
fromIntegral = forall a b. (Integral a, Num b) => a -> b
P.fromIntegral

instance FromIntegral Float Int where
  fromIntegral :: Int -> Float
fromIntegral = forall a b. (Integral a, Num b) => a -> b
P.fromIntegral

instance FromIntegral Int Int where
  fromIntegral :: Int -> Int
fromIntegral = forall a. a -> a
P.id

instance FromIntegral Integer Int where
  fromIntegral :: Int -> Integer
fromIntegral = forall a b. (Integral a, Num b) => a -> b
P.fromIntegral

instance FromIntegral Natural Int where
  fromIntegral :: Int -> Natural
fromIntegral = forall a b. (Integral a, Num b) => a -> b
P.fromIntegral

instance FromIntegral Int8 Int where
  fromIntegral :: Int -> Int8
fromIntegral = forall a b. (Integral a, Num b) => a -> b
P.fromIntegral

instance FromIntegral Int16 Int where
  fromIntegral :: Int -> Int16
fromIntegral = forall a b. (Integral a, Num b) => a -> b
P.fromIntegral

instance FromIntegral Int32 Int where
  fromIntegral :: Int -> Int32
fromIntegral = forall a b. (Integral a, Num b) => a -> b
P.fromIntegral

instance FromIntegral Int64 Int where
  fromIntegral :: Int -> Int64
fromIntegral = forall a b. (Integral a, Num b) => a -> b
P.fromIntegral

instance FromIntegral Word Int where
  fromIntegral :: Int -> Word
fromIntegral = forall a b. (Integral a, Num b) => a -> b
P.fromIntegral

instance FromIntegral Word8 Int where
  fromIntegral :: Int -> Word8
fromIntegral = forall a b. (Integral a, Num b) => a -> b
P.fromIntegral

instance FromIntegral Word16 Int where
  fromIntegral :: Int -> Word16
fromIntegral = forall a b. (Integral a, Num b) => a -> b
P.fromIntegral

instance FromIntegral Word32 Int where
  fromIntegral :: Int -> Word32
fromIntegral = forall a b. (Integral a, Num b) => a -> b
P.fromIntegral

instance FromIntegral Word64 Int where
  fromIntegral :: Int -> Word64
fromIntegral = forall a b. (Integral a, Num b) => a -> b
P.fromIntegral

instance FromIntegral Natural Natural where
  fromIntegral :: Natural -> Natural
fromIntegral = forall a. a -> a
P.id

instance FromIntegral Int8 Int8 where
  fromIntegral :: Int8 -> Int8
fromIntegral = forall a. a -> a
P.id

instance FromIntegral Int16 Int16 where
  fromIntegral :: Int16 -> Int16
fromIntegral = forall a. a -> a
P.id

instance FromIntegral Int32 Int32 where
  fromIntegral :: Int32 -> Int32
fromIntegral = forall a. a -> a
P.id

instance FromIntegral Int64 Int64 where
  fromIntegral :: Int64 -> Int64
fromIntegral = forall a. a -> a
P.id

instance FromIntegral Word Word where
  fromIntegral :: Word -> Word
fromIntegral = forall a. a -> a
P.id

instance FromIntegral Word8 Word8 where
  fromIntegral :: Word8 -> Word8
fromIntegral = forall a. a -> a
P.id

instance FromIntegral Word16 Word16 where
  fromIntegral :: Word16 -> Word16
fromIntegral = forall a. a -> a
P.id

instance FromIntegral Word32 Word32 where
  fromIntegral :: Word32 -> Word32
fromIntegral = forall a. a -> a
P.id

instance FromIntegral Word64 Word64 where
  fromIntegral :: Word64 -> Word64
fromIntegral = forall a. a -> a
P.id

-- | 'fromInteger' is special in two ways:
--
-- - numeric integral literals (like "42") are interpreted specifically as "fromInteger (42 :: GHC.Num.Integer)". The prelude version is used as default (or whatever fromInteger is in scope if RebindableSyntax is set).
--
-- - The default rules in < https://www.haskell.org/onlinereport/haskell2010/haskellch4.html#x10-750004.3 haskell2010> specify that constraints on 'fromInteger' need to be in a form @C v@, where v is a Num or a subclass of Num.
--
-- So a type synonym of `type FromInteger a = FromIntegral a Integer` doesn't work well with type defaulting; hence the need for a separate class.
class FromInteger a where
  fromInteger :: Integer -> a

instance FromInteger Double where
  fromInteger :: Integer -> Double
fromInteger = forall a. Num a => Integer -> a
P.fromInteger

instance FromInteger Float where
  fromInteger :: Integer -> Float
fromInteger = forall a. Num a => Integer -> a
P.fromInteger

instance FromInteger Int where
  fromInteger :: Integer -> Int
fromInteger = forall a. Num a => Integer -> a
P.fromInteger

instance FromInteger Integer where
  fromInteger :: Integer -> Integer
fromInteger = forall a. a -> a
P.id

instance FromInteger Natural where
  fromInteger :: Integer -> Natural
fromInteger = Integer -> Natural
naturalFromInteger

instance FromInteger Int8 where
  fromInteger :: Integer -> Int8
fromInteger = forall a. Num a => Integer -> a
P.fromInteger

instance FromInteger Int16 where
  fromInteger :: Integer -> Int16
fromInteger = forall a. Num a => Integer -> a
P.fromInteger

instance FromInteger Int32 where
  fromInteger :: Integer -> Int32
fromInteger = forall a. Num a => Integer -> a
P.fromInteger

instance FromInteger Int64 where
  fromInteger :: Integer -> Int64
fromInteger = forall a. Num a => Integer -> a
P.fromInteger

instance FromInteger Word where
  fromInteger :: Integer -> Word
fromInteger = forall a. Num a => Integer -> a
P.fromInteger

instance FromInteger Word8 where
  fromInteger :: Integer -> Word8
fromInteger = forall a. Num a => Integer -> a
P.fromInteger

instance FromInteger Word16 where
  fromInteger :: Integer -> Word16
fromInteger = forall a. Num a => Integer -> a
P.fromInteger

instance FromInteger Word32 where
  fromInteger :: Integer -> Word32
fromInteger = forall a. Num a => Integer -> a
P.fromInteger

instance FromInteger Word64 where
  fromInteger :: Integer -> Word64
fromInteger = forall a. Num a => Integer -> a
P.fromInteger

-- |
-- >>> even 2
-- True
even :: (P.Eq a, Integral a) => a -> P.Bool
even :: forall a. (Eq a, Integral a) => a -> Bool
even a
n = a
n forall a. Integral a => a -> a -> a
`rem` (forall a. Multiplicative a => a
one forall a. Additive a => a -> a -> a
+ forall a. Multiplicative a => a
one) forall a. Eq a => a -> a -> Bool
P.== forall a. Additive a => a
zero

-- |
-- >>> odd 3
-- True
odd :: (P.Eq a, Integral a) => a -> P.Bool
odd :: forall a. (Eq a, Integral a) => a -> Bool
odd = Bool -> Bool
P.not forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a. (Eq a, Integral a) => a -> Bool
even

infixr 8 ^^

-- | raise a number to an 'Integral' power
--
-- >>> 2 ^^ 3
-- 8.0
--
-- >>> 2 ^^ (-2)
-- 0.25
(^^) ::
  (P.Ord b, Divisive a, Subtractive b, Integral b) =>
  a ->
  b ->
  a
a
x0 ^^ :: forall b a.
(Ord b, Divisive a, Subtractive b, Integral b) =>
a -> b -> a
^^ b
y0 =
  case forall a. Ord a => a -> a -> Ordering
compare b
y0 forall a. Additive a => a
zero of
    Ordering
EQ -> forall a. Multiplicative a => a
one
    Ordering
GT -> forall {a} {t}. (Eq a, Integral a, Multiplicative t) => t -> a -> t
f a
x0 b
y0
    Ordering
LT -> forall a. Divisive a => a -> a
recip (a
x0 forall b a.
(Ord b, Divisive a, Subtractive b, Integral b) =>
a -> b -> a
^^ forall a. Subtractive a => a -> a
negate b
y0)
  where
    f :: t -> a -> t
f t
x a
y
      | forall a. (Eq a, Integral a) => a -> Bool
even a
y = t -> a -> t
f (t
x forall a. Multiplicative a => a -> a -> a
* t
x) (a
y forall a. Integral a => a -> a -> a
`quot` forall a. (Multiplicative a, Additive a) => a
two)
      | a
y forall a. Eq a => a -> a -> Bool
P.== forall a. Multiplicative a => a
one = t
x
      | Bool
P.otherwise = forall {a} {t}.
(Eq a, Integral a, Multiplicative t) =>
t -> a -> t -> t
g (t
x forall a. Multiplicative a => a -> a -> a
* t
x) (a
y forall a. Integral a => a -> a -> a
`quot` forall a. (Multiplicative a, Additive a) => a
two) t
x
    g :: t -> a -> t -> t
g t
x a
y t
z
      | forall a. (Eq a, Integral a) => a -> Bool
even a
y = t -> a -> t -> t
g (t
x forall a. Multiplicative a => a -> a -> a
* t
x) (a
y forall a. Integral a => a -> a -> a
`quot` forall a. (Multiplicative a, Additive a) => a
two) t
z
      | a
y forall a. Eq a => a -> a -> Bool
P.== forall a. Multiplicative a => a
one = t
x forall a. Multiplicative a => a -> a -> a
* t
z
      | Bool
P.otherwise = t -> a -> t -> t
g (t
x forall a. Multiplicative a => a -> a -> a
* t
x) (a
y forall a. Integral a => a -> a -> a
`quot` forall a. (Multiplicative a, Additive a) => a
two) (t
x forall a. Multiplicative a => a -> a -> a
* t
z)

infixr 8 ^

-- | raise a number to an 'Int' power
--
-- Note: This differs from (^) found in prelude which is a partial function (it errors on negative integrals). This monomorphic version is provided to help reduce ambiguous type noise in common usages of this sign.
--
-- >>> 2 ^ 3
-- 8.0
--
-- >>> 2 ^ (-2)
-- 0.25
(^) ::
  (Divisive a) => a -> Int -> a
^ :: forall a. Divisive a => a -> Int -> a
(^) a
x Int
n = a
x forall b a.
(Ord b, Divisive a, Subtractive b, Integral b) =>
a -> b -> a
^^ Int
n