{-# LANGUAGE DataKinds #-}
{-# LANGUAGE DerivingVia #-}
{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE TemplateHaskell #-}
{-# LANGUAGE TypeApplications #-}
{-# LANGUAGE TypeFamilies #-}
{-# LANGUAGE UndecidableInstances #-}
{-# OPTIONS_GHC -fno-omit-interface-pragmas #-}
{-# OPTIONS_GHC -fno-specialise #-}

module PlutusLedgerApi.V4.Ratio
  ( Rational (..)
  , ratio
  , unsafeRatio
  , numerator
  , denominator
  , fromHaskellRatio
  , toHaskellRatio
  , fromGHC
  , toGHC
  ) where

import Data.Aeson (FromJSON, ToJSON)
import Data.Ratio qualified as Haskell
import GHC.Generics (Generic)
import PlutusLedgerApi.V4.Internal (ListEncoded (..))
import PlutusTx qualified
import PlutusTx.Blueprint.Class (HasBlueprintSchema (..))
import PlutusTx.Blueprint.Definition (HasBlueprintDefinition (..))
import PlutusTx.Prelude qualified as PlutusTx
import PlutusTx.Ratio qualified as Ratio
import Prettyprinter (Pretty)
import Prelude hiding (Rational)

newtype Rational = Rational {Rational -> Rational
unRational :: Ratio.Rational}
  deriving stock ((forall x. Rational -> Rep Rational x)
-> (forall x. Rep Rational x -> Rational) -> Generic Rational
forall x. Rep Rational x -> Rational
forall x. Rational -> Rep Rational x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
$cfrom :: forall x. Rational -> Rep Rational x
from :: forall x. Rational -> Rep Rational x
$cto :: forall x. Rep Rational x -> Rational
to :: forall x. Rep Rational x -> Rational
Generic)
  deriving newtype
    ( Rational -> Rational -> Bool
(Rational -> Rational -> Bool)
-> (Rational -> Rational -> Bool) -> Eq Rational
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: Rational -> Rational -> Bool
== :: Rational -> Rational -> Bool
$c/= :: Rational -> Rational -> Bool
/= :: Rational -> Rational -> Bool
Eq
    , Eq Rational
Eq Rational =>
(Rational -> Rational -> Ordering)
-> (Rational -> Rational -> Bool)
-> (Rational -> Rational -> Bool)
-> (Rational -> Rational -> Bool)
-> (Rational -> Rational -> Bool)
-> (Rational -> Rational -> Rational)
-> (Rational -> Rational -> Rational)
-> Ord Rational
Rational -> Rational -> Bool
Rational -> Rational -> Ordering
Rational -> Rational -> Rational
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
$ccompare :: Rational -> Rational -> Ordering
compare :: Rational -> Rational -> Ordering
$c< :: Rational -> Rational -> Bool
< :: Rational -> Rational -> Bool
$c<= :: Rational -> Rational -> Bool
<= :: Rational -> Rational -> Bool
$c> :: Rational -> Rational -> Bool
> :: Rational -> Rational -> Bool
$c>= :: Rational -> Rational -> Bool
>= :: Rational -> Rational -> Bool
$cmax :: Rational -> Rational -> Rational
max :: Rational -> Rational -> Rational
$cmin :: Rational -> Rational -> Rational
min :: Rational -> Rational -> Rational
Ord
    , Int -> Rational -> ShowS
[Rational] -> ShowS
Rational -> String
(Int -> Rational -> ShowS)
-> (Rational -> String) -> ([Rational] -> ShowS) -> Show Rational
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> Rational -> ShowS
showsPrec :: Int -> Rational -> ShowS
$cshow :: Rational -> String
show :: Rational -> String
$cshowList :: [Rational] -> ShowS
showList :: [Rational] -> ShowS
Show
    , (forall ann. Rational -> Doc ann)
-> (forall ann. [Rational] -> Doc ann) -> Pretty Rational
forall ann. [Rational] -> Doc ann
forall ann. Rational -> Doc ann
forall a.
(forall ann. a -> Doc ann)
-> (forall ann. [a] -> Doc ann) -> Pretty a
$cpretty :: forall ann. Rational -> Doc ann
pretty :: forall ann. Rational -> Doc ann
$cprettyList :: forall ann. [Rational] -> Doc ann
prettyList :: forall ann. [Rational] -> Doc ann
Pretty
    , [Rational] -> Value
[Rational] -> Encoding
Rational -> Bool
Rational -> Value
Rational -> Encoding
(Rational -> Value)
-> (Rational -> Encoding)
-> ([Rational] -> Value)
-> ([Rational] -> Encoding)
-> (Rational -> Bool)
-> ToJSON Rational
forall a.
(a -> Value)
-> (a -> Encoding)
-> ([a] -> Value)
-> ([a] -> Encoding)
-> (a -> Bool)
-> ToJSON a
$ctoJSON :: Rational -> Value
toJSON :: Rational -> Value
$ctoEncoding :: Rational -> Encoding
toEncoding :: Rational -> Encoding
$ctoJSONList :: [Rational] -> Value
toJSONList :: [Rational] -> Value
$ctoEncodingList :: [Rational] -> Encoding
toEncodingList :: [Rational] -> Encoding
$comitField :: Rational -> Bool
omitField :: Rational -> Bool
ToJSON
    , Maybe Rational
Value -> Parser [Rational]
Value -> Parser Rational
(Value -> Parser Rational)
-> (Value -> Parser [Rational])
-> Maybe Rational
-> FromJSON Rational
forall a.
(Value -> Parser a)
-> (Value -> Parser [a]) -> Maybe a -> FromJSON a
$cparseJSON :: Value -> Parser Rational
parseJSON :: Value -> Parser Rational
$cparseJSONList :: Value -> Parser [Rational]
parseJSONList :: Value -> Parser [Rational]
$comittedField :: Maybe Rational
omittedField :: Maybe Rational
FromJSON
    , Rational -> Rational -> Bool
(Rational -> Rational -> Bool) -> Eq Rational
forall a. (a -> a -> Bool) -> Eq a
$c== :: Rational -> Rational -> Bool
== :: Rational -> Rational -> Bool
PlutusTx.Eq
    , Eq Rational
Eq Rational =>
(Rational -> Rational -> Ordering)
-> (Rational -> Rational -> Bool)
-> (Rational -> Rational -> Bool)
-> (Rational -> Rational -> Bool)
-> (Rational -> Rational -> Bool)
-> (Rational -> Rational -> Rational)
-> (Rational -> Rational -> Rational)
-> Ord Rational
Rational -> Rational -> Bool
Rational -> Rational -> Ordering
Rational -> Rational -> Rational
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
$ccompare :: Rational -> Rational -> Ordering
compare :: Rational -> Rational -> Ordering
$c< :: Rational -> Rational -> Bool
< :: Rational -> Rational -> Bool
$c<= :: Rational -> Rational -> Bool
<= :: Rational -> Rational -> Bool
$c> :: Rational -> Rational -> Bool
> :: Rational -> Rational -> Bool
$c>= :: Rational -> Rational -> Bool
>= :: Rational -> Rational -> Bool
$cmax :: Rational -> Rational -> Rational
max :: Rational -> Rational -> Rational
$cmin :: Rational -> Rational -> Rational
min :: Rational -> Rational -> Rational
PlutusTx.Ord
    , Integer -> Rational
Rational -> Integer
Rational -> Rational
Rational -> Rational -> [Rational]
Rational -> Rational -> Rational -> [Rational]
(Rational -> Rational)
-> (Rational -> Rational)
-> (Integer -> Rational)
-> (Rational -> Integer)
-> (Rational -> Rational -> [Rational])
-> (Rational -> Rational -> Rational -> [Rational])
-> Enum Rational
forall a.
(a -> a)
-> (a -> a)
-> (Integer -> a)
-> (a -> Integer)
-> (a -> a -> [a])
-> (a -> a -> a -> [a])
-> Enum a
$csucc :: Rational -> Rational
succ :: Rational -> Rational
$cpred :: Rational -> Rational
pred :: Rational -> Rational
$ctoEnum :: Integer -> Rational
toEnum :: Integer -> Rational
$cfromEnum :: Rational -> Integer
fromEnum :: Rational -> Integer
$cenumFromTo :: Rational -> Rational -> [Rational]
enumFromTo :: Rational -> Rational -> [Rational]
$cenumFromThenTo :: Rational -> Rational -> Rational -> [Rational]
enumFromThenTo :: Rational -> Rational -> Rational -> [Rational]
PlutusTx.Enum
    , Rational -> Rational -> Rational
(Rational -> Rational -> Rational) -> AdditiveSemigroup Rational
forall a. (a -> a -> a) -> AdditiveSemigroup a
$c+ :: Rational -> Rational -> Rational
+ :: Rational -> Rational -> Rational
PlutusTx.AdditiveSemigroup
    , AdditiveSemigroup Rational
Rational
AdditiveSemigroup Rational => Rational -> AdditiveMonoid Rational
forall a. AdditiveSemigroup a => a -> AdditiveMonoid a
$czero :: Rational
zero :: Rational
PlutusTx.AdditiveMonoid
    , AdditiveMonoid Rational
AdditiveMonoid Rational =>
(Rational -> Rational -> Rational) -> AdditiveGroup Rational
Rational -> Rational -> Rational
forall a. AdditiveMonoid a => (a -> a -> a) -> AdditiveGroup a
$c- :: Rational -> Rational -> Rational
- :: Rational -> Rational -> Rational
PlutusTx.AdditiveGroup
    , Rational -> Rational -> Rational
(Rational -> Rational -> Rational)
-> MultiplicativeSemigroup Rational
forall a. (a -> a -> a) -> MultiplicativeSemigroup a
$c* :: Rational -> Rational -> Rational
* :: Rational -> Rational -> Rational
PlutusTx.MultiplicativeSemigroup
    , MultiplicativeSemigroup Rational
Rational
MultiplicativeSemigroup Rational =>
Rational -> MultiplicativeMonoid Rational
forall a. MultiplicativeSemigroup a => a -> MultiplicativeMonoid a
$cone :: Rational
one :: Rational
PlutusTx.MultiplicativeMonoid
    , PlutusTx.Module Integer
    )
  deriving
    (Rational -> BuiltinData
(Rational -> BuiltinData) -> ToData Rational
forall a. (a -> BuiltinData) -> ToData a
$ctoBuiltinData :: Rational -> BuiltinData
toBuiltinData :: Rational -> BuiltinData
PlutusTx.ToData, BuiltinData -> Maybe Rational
(BuiltinData -> Maybe Rational) -> FromData Rational
forall a. (BuiltinData -> Maybe a) -> FromData a
$cfromBuiltinData :: BuiltinData -> Maybe Rational
fromBuiltinData :: BuiltinData -> Maybe Rational
PlutusTx.FromData, BuiltinData -> Rational
(BuiltinData -> Rational) -> UnsafeFromData Rational
forall a. (BuiltinData -> a) -> UnsafeFromData a
$cunsafeFromBuiltinData :: BuiltinData -> Rational
unsafeFromBuiltinData :: BuiltinData -> Rational
PlutusTx.UnsafeFromData)
    via ListEncoded Ratio.Rational

instance HasBlueprintDefinition Rational where
  type Unroll Rational = '[Rational, Integer]

instance HasBlueprintSchema Ratio.Rational referencedTypes => HasBlueprintSchema Rational referencedTypes where
  schema :: Schema referencedTypes
schema = forall t (referencedTypes :: [*]).
HasBlueprintSchema t referencedTypes =>
Schema referencedTypes
schema @(ListEncoded Ratio.Rational) @referencedTypes

PlutusTx.makeLift ''Rational

{-# INLINEABLE ratio #-}
ratio :: Integer -> Integer -> Maybe Rational
ratio :: Integer -> Integer -> Maybe Rational
ratio Integer
numeratorValue Integer
denominatorValue =
  Rational -> Rational
Rational (Rational -> Rational) -> Maybe Rational -> Maybe Rational
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
PlutusTx.<$> Integer -> Integer -> Maybe Rational
Ratio.ratio Integer
numeratorValue Integer
denominatorValue

{-# INLINEABLE unsafeRatio #-}
unsafeRatio :: Integer -> Integer -> Rational
unsafeRatio :: Integer -> Integer -> Rational
unsafeRatio Integer
numeratorValue Integer
denominatorValue = Rational -> Rational
Rational (Integer -> Integer -> Rational
Ratio.unsafeRatio Integer
numeratorValue Integer
denominatorValue)

{-# INLINEABLE numerator #-}
numerator :: Rational -> Integer
numerator :: Rational -> Integer
numerator (Rational Rational
value) = Rational -> Integer
Ratio.numerator Rational
value

{-# INLINEABLE denominator #-}
denominator :: Rational -> Integer
denominator :: Rational -> Integer
denominator (Rational Rational
value) = Rational -> Integer
Ratio.denominator Rational
value

fromHaskellRatio :: Haskell.Rational -> Rational
fromHaskellRatio :: Rational -> Rational
fromHaskellRatio Rational
value = Rational -> Rational
Rational (Rational -> Rational
Ratio.fromHaskellRatio Rational
value)

toHaskellRatio :: Rational -> Haskell.Rational
toHaskellRatio :: Rational -> Rational
toHaskellRatio (Rational Rational
value) = Rational -> Rational
Ratio.toHaskellRatio Rational
value

fromGHC :: Haskell.Rational -> Rational
fromGHC :: Rational -> Rational
fromGHC = Rational -> Rational
fromHaskellRatio

toGHC :: Rational -> Haskell.Rational
toGHC :: Rational -> Rational
toGHC = Rational -> Rational
toHaskellRatio