{-# LANGUAGE TemplateHaskell #-}
{-# OPTIONS_GHC -Wno-orphans #-}
{-# LANGUAGE DataKinds #-}
{-# LANGUAGE PolyKinds #-}
{-# LANGUAGE RankNTypes #-}
{-# LANGUAGE GeneralizedNewtypeDeriving #-}
{-# LANGUAGE StandaloneDeriving #-}
{-|
    Module      :  AERN2.MP.WithCurrentPrec.Comparisons
    Description :  WithCurrentPrec order relations and operations
    Copyright   :  (c) Michal Konecny
    License     :  BSD3

    Maintainer  :  mikkonecny@gmail.com
    Stability   :  experimental
    Portability :  portable

    WithCurrentPrec order relations and operations
-}
module AERN2.MP.WithCurrentPrec.Comparisons
()
where

import MixedTypesNumPrelude
-- import qualified Prelude as P
-- import Text.Printf

-- import qualified Numeric.CollectErrors as CN

import AERN2.MP.Dyadic

import AERN2.MP.WithCurrentPrec.Type

instance
    (HasEqAsymmetric t1 t2, p1 ~ p2)
    =>
    HasEqAsymmetric (WithCurrentPrec p1 t1) (WithCurrentPrec p2 t2) 
    where
    type EqCompareType (WithCurrentPrec p1 t1) (WithCurrentPrec p2 t2) = EqCompareType t1 t2
    equalTo :: WithCurrentPrec p1 t1
-> WithCurrentPrec p2 t2
-> EqCompareType (WithCurrentPrec p1 t1) (WithCurrentPrec p2 t2)
equalTo = (t1 -> t2 -> EqCompareType t1 t2)
-> WithCurrentPrec p1 t1
-> WithCurrentPrec p2 t2
-> EqCompareType t1 t2
forall k (p1 :: k) (p2 :: k) t1 t2 t3.
(p1 ~ p2) =>
(t1 -> t2 -> t3)
-> WithCurrentPrec p1 t1 -> WithCurrentPrec p2 t2 -> t3
lift2P t1 -> t2 -> EqCompareType t1 t2
forall a b. HasEqAsymmetric a b => a -> b -> EqCompareType a b
equalTo
    notEqualTo :: WithCurrentPrec p1 t1
-> WithCurrentPrec p2 t2
-> EqCompareType (WithCurrentPrec p1 t1) (WithCurrentPrec p2 t2)
notEqualTo = (t1 -> t2 -> EqCompareType t1 t2)
-> WithCurrentPrec p1 t1
-> WithCurrentPrec p2 t2
-> EqCompareType t1 t2
forall k (p1 :: k) (p2 :: k) t1 t2 t3.
(p1 ~ p2) =>
(t1 -> t2 -> t3)
-> WithCurrentPrec p1 t1 -> WithCurrentPrec p2 t2 -> t3
lift2P t1 -> t2 -> EqCompareType t1 t2
forall a b. HasEqAsymmetric a b => a -> b -> EqCompareType a b
notEqualTo

instance
    (HasOrderAsymmetric t1 t2, p1 ~ p2)
    =>
    HasOrderAsymmetric (WithCurrentPrec p1 t1) (WithCurrentPrec p2 t2) 
    where
    type OrderCompareType (WithCurrentPrec p1 t1) (WithCurrentPrec p2 t2) = OrderCompareType t1 t2
    greaterThan :: WithCurrentPrec p1 t1
-> WithCurrentPrec p2 t2
-> OrderCompareType (WithCurrentPrec p1 t1) (WithCurrentPrec p2 t2)
greaterThan = (t1 -> t2 -> OrderCompareType t1 t2)
-> WithCurrentPrec p1 t1
-> WithCurrentPrec p2 t2
-> OrderCompareType t1 t2
forall k (p1 :: k) (p2 :: k) t1 t2 t3.
(p1 ~ p2) =>
(t1 -> t2 -> t3)
-> WithCurrentPrec p1 t1 -> WithCurrentPrec p2 t2 -> t3
lift2P t1 -> t2 -> OrderCompareType t1 t2
forall a b.
HasOrderAsymmetric a b =>
a -> b -> OrderCompareType a b
greaterThan
    lessThan :: WithCurrentPrec p1 t1
-> WithCurrentPrec p2 t2
-> OrderCompareType (WithCurrentPrec p1 t1) (WithCurrentPrec p2 t2)
lessThan = (t1 -> t2 -> OrderCompareType t1 t2)
-> WithCurrentPrec p1 t1
-> WithCurrentPrec p2 t2
-> OrderCompareType t1 t2
forall k (p1 :: k) (p2 :: k) t1 t2 t3.
(p1 ~ p2) =>
(t1 -> t2 -> t3)
-> WithCurrentPrec p1 t1 -> WithCurrentPrec p2 t2 -> t3
lift2P t1 -> t2 -> OrderCompareType t1 t2
forall a b.
HasOrderAsymmetric a b =>
a -> b -> OrderCompareType a b
lessThan
    geq :: WithCurrentPrec p1 t1
-> WithCurrentPrec p2 t2
-> OrderCompareType (WithCurrentPrec p1 t1) (WithCurrentPrec p2 t2)
geq = (t1 -> t2 -> OrderCompareType t1 t2)
-> WithCurrentPrec p1 t1
-> WithCurrentPrec p2 t2
-> OrderCompareType t1 t2
forall k (p1 :: k) (p2 :: k) t1 t2 t3.
(p1 ~ p2) =>
(t1 -> t2 -> t3)
-> WithCurrentPrec p1 t1 -> WithCurrentPrec p2 t2 -> t3
lift2P t1 -> t2 -> OrderCompareType t1 t2
forall a b.
HasOrderAsymmetric a b =>
a -> b -> OrderCompareType a b
geq
    leq :: WithCurrentPrec p1 t1
-> WithCurrentPrec p2 t2
-> OrderCompareType (WithCurrentPrec p1 t1) (WithCurrentPrec p2 t2)
leq = (t1 -> t2 -> OrderCompareType t1 t2)
-> WithCurrentPrec p1 t1
-> WithCurrentPrec p2 t2
-> OrderCompareType t1 t2
forall k (p1 :: k) (p2 :: k) t1 t2 t3.
(p1 ~ p2) =>
(t1 -> t2 -> t3)
-> WithCurrentPrec p1 t1 -> WithCurrentPrec p2 t2 -> t3
lift2P t1 -> t2 -> OrderCompareType t1 t2
forall a b.
HasOrderAsymmetric a b =>
a -> b -> OrderCompareType a b
leq

instance
    (CanAbs t)
    =>
    CanAbs (WithCurrentPrec p t)
    where
    type AbsType (WithCurrentPrec p t) = WithCurrentPrec p (AbsType t)
    abs :: WithCurrentPrec p t -> AbsType (WithCurrentPrec p t)
abs = (t -> AbsType t)
-> WithCurrentPrec p t -> WithCurrentPrec p (AbsType t)
forall k t1 t2 (p :: k).
(t1 -> t2) -> WithCurrentPrec p t1 -> WithCurrentPrec p t2
lift1 t -> AbsType t
forall t. CanAbs t => t -> AbsType t
abs

instance
    (CanMinMaxAsymmetric t1 t2, p1 ~ p2)
    =>
    CanMinMaxAsymmetric (WithCurrentPrec p1 t1) (WithCurrentPrec p2 t2) 
    where
    type MinMaxType (WithCurrentPrec p1 t1) (WithCurrentPrec p2 t2) = WithCurrentPrec p1 (MinMaxType t1 t2)
    min :: WithCurrentPrec p1 t1
-> WithCurrentPrec p2 t2
-> MinMaxType (WithCurrentPrec p1 t1) (WithCurrentPrec p2 t2)
min = (t1 -> t2 -> MinMaxType t1 t2)
-> WithCurrentPrec p1 t1
-> WithCurrentPrec p2 t2
-> WithCurrentPrec p1 (MinMaxType t1 t2)
forall k (p1 :: k) (p2 :: k) t1 t2 t3.
(p1 ~ p2) =>
(t1 -> t2 -> t3)
-> WithCurrentPrec p1 t1
-> WithCurrentPrec p2 t2
-> WithCurrentPrec p1 t3
lift2 t1 -> t2 -> MinMaxType t1 t2
forall t1 t2.
CanMinMaxAsymmetric t1 t2 =>
t1 -> t2 -> MinMaxType t1 t2
min
    max :: WithCurrentPrec p1 t1
-> WithCurrentPrec p2 t2
-> MinMaxType (WithCurrentPrec p1 t1) (WithCurrentPrec p2 t2)
max = (t1 -> t2 -> MinMaxType t1 t2)
-> WithCurrentPrec p1 t1
-> WithCurrentPrec p2 t2
-> WithCurrentPrec p1 (MinMaxType t1 t2)
forall k (p1 :: k) (p2 :: k) t1 t2 t3.
(p1 ~ p2) =>
(t1 -> t2 -> t3)
-> WithCurrentPrec p1 t1
-> WithCurrentPrec p2 t2
-> WithCurrentPrec p1 t3
lift2 t1 -> t2 -> MinMaxType t1 t2
forall t1 t2.
CanMinMaxAsymmetric t1 t2 =>
t1 -> t2 -> MinMaxType t1 t2
max

-- mixed type instances:

$(declForTypes
  [[t| Integer |], [t| Int |], [t| Rational |], [t| Dyadic |]]
  (\ t -> [d|

    -- min, max

    instance
      (CanMinMaxAsymmetric a $t)
      => 
      CanMinMaxAsymmetric (WithCurrentPrec p a) $t
      where
      type MinMaxType (WithCurrentPrec p a) $t = WithCurrentPrec p (MinMaxType a $t)
      min = lift1T min
      max = lift1T max

    instance
      (CanMinMaxAsymmetric a (CN $t))
      => 
      CanMinMaxAsymmetric (WithCurrentPrec p a) (CN $t)
      where
      type MinMaxType (WithCurrentPrec p a) (CN $t) = WithCurrentPrec p (MinMaxType a (CN $t))
      min = lift1T min
      max = lift1T max

    instance
      (CanMinMaxAsymmetric $t a)
      => 
      CanMinMaxAsymmetric $t (WithCurrentPrec p a)
      where
      type MinMaxType $t (WithCurrentPrec p a) = WithCurrentPrec p (MinMaxType $t a)
      min = liftT1 min
      max = liftT1 max

    instance
      (CanMinMaxAsymmetric (CN $t) a)
      => 
      CanMinMaxAsymmetric (CN $t) (WithCurrentPrec p a)
      where
      type MinMaxType (CN $t) (WithCurrentPrec p a) = WithCurrentPrec p (MinMaxType (CN $t) a)
      min = liftT1 min
      max = liftT1 max

    -- equality

    instance
      (HasEqAsymmetric a $t)
      => 
      HasEqAsymmetric (WithCurrentPrec p a) $t
      where
      type EqCompareType (WithCurrentPrec p a) $t = EqCompareType a $t
      equalTo = lift1TP (==)
      notEqualTo = lift1TP (/=)

    instance
      (HasEqAsymmetric a (CN $t))
      => 
      HasEqAsymmetric (WithCurrentPrec p a) (CN $t)
      where
      type EqCompareType (WithCurrentPrec p a) (CN $t) = EqCompareType a (CN $t)
      equalTo = lift1TP (==)
      notEqualTo = lift1TP (/=)

    instance
      (HasEqAsymmetric $t a)
      =>
      HasEqAsymmetric $t (WithCurrentPrec p a)
      where
      type EqCompareType $t (WithCurrentPrec p a) = EqCompareType $t a
      equalTo = liftT1P (==)
      notEqualTo = liftT1P (/=)

    instance
      (HasEqAsymmetric (CN $t) a)
      =>
      HasEqAsymmetric (CN $t) (WithCurrentPrec p a)
      where
      type EqCompareType (CN $t) (WithCurrentPrec p a) = EqCompareType (CN $t) a
      equalTo = liftT1P (==)
      notEqualTo = liftT1P (/=)

    -- order

    instance
      (HasOrderAsymmetric a $t)
      => 
      HasOrderAsymmetric (WithCurrentPrec p a) $t
      where
      type OrderCompareType (WithCurrentPrec p a) $t = OrderCompareType a $t
      lessThan = lift1TP lessThan
      greaterThan = lift1TP greaterThan
      leq = lift1TP leq
      geq = lift1TP geq

    instance
      (HasOrderAsymmetric a (CN $t))
      => 
      HasOrderAsymmetric (WithCurrentPrec p a) (CN $t)
      where
      type OrderCompareType (WithCurrentPrec p a) (CN $t) = OrderCompareType a (CN $t)
      lessThan = lift1TP lessThan
      greaterThan = lift1TP greaterThan
      leq = lift1TP leq
      geq = lift1TP geq

    instance
      (HasOrderAsymmetric $t a)
      =>
      HasOrderAsymmetric $t (WithCurrentPrec p a)
      where
      type OrderCompareType $t (WithCurrentPrec p a) = OrderCompareType $t a
      lessThan = liftT1P lessThan
      greaterThan = liftT1P greaterThan
      leq = liftT1P leq
      geq = liftT1P geq

    instance
      (HasOrderAsymmetric (CN $t) a)
      =>
      HasOrderAsymmetric (CN $t) (WithCurrentPrec p a)
      where
      type OrderCompareType (CN $t) (WithCurrentPrec p a) = OrderCompareType (CN $t) a
      lessThan = liftT1P lessThan
      greaterThan = liftT1P greaterThan
      leq = liftT1P leq
      geq = liftT1P geq

  |]))