-- | This module provides the 'PrettyCooked' class and instances for common
-- Plutus types.  We don't rely on 'Pretty' from "Prettyprinter" in order to
-- define better printers for Plutus types which already have instances of
-- 'Pretty'. Also, 'PrettyCooked' makes it possible to optionally modify pretty
-- printing settings 'PrettyCookedOpts' (e.g. length of printed hashes).
--
-- When defining a new 'PrettyCooked' instance, prefer implementing
-- 'prettyCookedOpt' and relay the option parameter to other printers.
module Cooked.Pretty.Class
  ( PrettyCooked (..),
    printCookedOpt,
    printCooked,
  )
where

import Cooked.Conversion.ToHash
import Cooked.Pretty.Common
import Cooked.Pretty.Options
import Data.Default
import Data.Ratio
import Ledger.Index qualified as Ledger
import Ledger.Scripts qualified as Ledger
import Ledger.Tx.CardanoAPI qualified as Ledger
import Plutus.Script.Utils.Scripts qualified as Script
import Plutus.Script.Utils.Value qualified as Script
import PlutusLedgerApi.V3 qualified as Api
import Prettyprinter ((<+>))
import Prettyprinter qualified as PP
import Prettyprinter.Render.Text qualified as PP

class PrettyCooked a where
  prettyCooked :: a -> DocCooked
  prettyCooked = PrettyCookedOpts -> a -> DocCooked
forall a. PrettyCooked a => PrettyCookedOpts -> a -> DocCooked
prettyCookedOpt PrettyCookedOpts
forall a. Default a => a
def
  prettyCookedOpt :: PrettyCookedOpts -> a -> DocCooked
  prettyCookedOpt PrettyCookedOpts
_ = a -> DocCooked
forall a. PrettyCooked a => a -> DocCooked
prettyCooked

-- | Use this in the REPL as an alternative to the default 'print' function when
-- dealing with pretty-printable cooked values.
--
-- For example, @printCookedOpt def runMockChain i0 foo@
printCookedOpt :: (PrettyCooked a) => PrettyCookedOpts -> a -> IO ()
printCookedOpt :: forall a. PrettyCooked a => PrettyCookedOpts -> a -> IO ()
printCookedOpt PrettyCookedOpts
opts a
e = DocCooked -> IO ()
forall ann. Doc ann -> IO ()
PP.putDoc (DocCooked -> IO ()) -> DocCooked -> IO ()
forall a b. (a -> b) -> a -> b
$ PrettyCookedOpts -> a -> DocCooked
forall a. PrettyCooked a => PrettyCookedOpts -> a -> DocCooked
prettyCookedOpt PrettyCookedOpts
opts a
e DocCooked -> DocCooked -> DocCooked
forall ann. Doc ann -> Doc ann -> Doc ann
<+> DocCooked
forall ann. Doc ann
PP.line

-- | Version of 'printCookedOpt' that uses default pretty printing options.
printCooked :: (PrettyCooked a) => a -> IO ()
printCooked :: forall a. PrettyCooked a => a -> IO ()
printCooked = PrettyCookedOpts -> a -> IO ()
forall a. PrettyCooked a => PrettyCookedOpts -> a -> IO ()
printCookedOpt PrettyCookedOpts
forall a. Default a => a
def

instance PrettyCooked Api.TxId where
  prettyCookedOpt :: PrettyCookedOpts -> TxId -> DocCooked
prettyCookedOpt PrettyCookedOpts
opts = PrettyCookedHashOpts -> BuiltinByteString -> DocCooked
prettyHash (PrettyCookedOpts -> PrettyCookedHashOpts
pcOptHashes PrettyCookedOpts
opts) (BuiltinByteString -> DocCooked)
-> (TxId -> BuiltinByteString) -> TxId -> DocCooked
forall b c a. (b -> c) -> (a -> b) -> a -> c
. TxId -> BuiltinByteString
forall a. ToHash a => a -> BuiltinByteString
toHash

instance PrettyCooked Api.TxOutRef where
  prettyCookedOpt :: PrettyCookedOpts -> TxOutRef -> DocCooked
prettyCookedOpt PrettyCookedOpts
opts (Api.TxOutRef TxId
txId Integer
index) =
    PrettyCookedHashOpts -> BuiltinByteString -> DocCooked
prettyHash (PrettyCookedOpts -> PrettyCookedHashOpts
pcOptHashes PrettyCookedOpts
opts) (TxId -> BuiltinByteString
forall a. ToHash a => a -> BuiltinByteString
toHash TxId
txId) DocCooked -> DocCooked -> DocCooked
forall a. Semigroup a => a -> a -> a
<> DocCooked
"!" DocCooked -> DocCooked -> DocCooked
forall a. Semigroup a => a -> a -> a
<> PrettyCookedOpts -> Integer -> DocCooked
forall a. PrettyCooked a => PrettyCookedOpts -> a -> DocCooked
prettyCookedOpt PrettyCookedOpts
opts Integer
index

instance PrettyCooked (Script.Versioned Script.MintingPolicy) where
  prettyCookedOpt :: PrettyCookedOpts -> Versioned MintingPolicy -> DocCooked
prettyCookedOpt PrettyCookedOpts
opts = PrettyCookedHashOpts -> BuiltinByteString -> DocCooked
prettyHash (PrettyCookedOpts -> PrettyCookedHashOpts
pcOptHashes PrettyCookedOpts
opts) (BuiltinByteString -> DocCooked)
-> (Versioned MintingPolicy -> BuiltinByteString)
-> Versioned MintingPolicy
-> DocCooked
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Versioned MintingPolicy -> BuiltinByteString
forall a. ToHash a => a -> BuiltinByteString
toHash

instance PrettyCooked (Script.Versioned Script.Script) where
  prettyCookedOpt :: PrettyCookedOpts -> Versioned Script -> DocCooked
prettyCookedOpt PrettyCookedOpts
opts = PrettyCookedHashOpts -> BuiltinByteString -> DocCooked
prettyHash (PrettyCookedOpts -> PrettyCookedHashOpts
pcOptHashes PrettyCookedOpts
opts) (BuiltinByteString -> DocCooked)
-> (Versioned Script -> BuiltinByteString)
-> Versioned Script
-> DocCooked
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Versioned Script -> BuiltinByteString
forall a. ToHash a => a -> BuiltinByteString
toHash

instance PrettyCooked Api.Address where
  prettyCookedOpt :: PrettyCookedOpts -> Address -> DocCooked
prettyCookedOpt PrettyCookedOpts
opts (Api.Address Credential
addrCr Maybe StakingCredential
Nothing) = PrettyCookedOpts -> Credential -> DocCooked
forall a. PrettyCooked a => PrettyCookedOpts -> a -> DocCooked
prettyCookedOpt PrettyCookedOpts
opts Credential
addrCr
  prettyCookedOpt PrettyCookedOpts
opts (Api.Address Credential
addrCr (Just (Api.StakingHash Credential
stakCr))) =
    PrettyCookedOpts -> Credential -> DocCooked
forall a. PrettyCooked a => PrettyCookedOpts -> a -> DocCooked
prettyCookedOpt PrettyCookedOpts
opts Credential
addrCr DocCooked -> DocCooked -> DocCooked
forall ann. Doc ann -> Doc ann -> Doc ann
<+> DocCooked -> DocCooked
forall ann. Doc ann -> Doc ann
PP.angles (DocCooked
"staking:" DocCooked -> DocCooked -> DocCooked
forall ann. Doc ann -> Doc ann -> Doc ann
<+> PrettyCookedOpts -> Credential -> DocCooked
forall a. PrettyCooked a => PrettyCookedOpts -> a -> DocCooked
prettyCookedOpt PrettyCookedOpts
opts Credential
stakCr)
  prettyCookedOpt PrettyCookedOpts
opts (Api.Address Credential
addrCr (Just (Api.StakingPtr Integer
p1 Integer
p2 Integer
p3))) =
    PrettyCookedOpts -> Credential -> DocCooked
forall a. PrettyCooked a => PrettyCookedOpts -> a -> DocCooked
prettyCookedOpt PrettyCookedOpts
opts Credential
addrCr DocCooked -> DocCooked -> DocCooked
forall ann. Doc ann -> Doc ann -> Doc ann
<+> DocCooked -> DocCooked
forall ann. Doc ann -> Doc ann
PP.angles (DocCooked
"staking:" DocCooked -> DocCooked -> DocCooked
forall ann. Doc ann -> Doc ann -> Doc ann
<+> (Integer, Integer, Integer) -> DocCooked
forall ann. (Integer, Integer, Integer) -> Doc ann
forall a ann. Pretty a => a -> Doc ann
PP.pretty (Integer
p1, Integer
p2, Integer
p3))

instance PrettyCooked Api.PubKeyHash where
  prettyCookedOpt :: PrettyCookedOpts -> PubKeyHash -> DocCooked
prettyCookedOpt PrettyCookedOpts
opts = PrettyCookedHashOpts -> BuiltinByteString -> DocCooked
prettyHash (PrettyCookedOpts -> PrettyCookedHashOpts
pcOptHashes PrettyCookedOpts
opts) (BuiltinByteString -> DocCooked)
-> (PubKeyHash -> BuiltinByteString) -> PubKeyHash -> DocCooked
forall b c a. (b -> c) -> (a -> b) -> a -> c
. PubKeyHash -> BuiltinByteString
forall a. ToHash a => a -> BuiltinByteString
toHash

instance PrettyCooked Api.Credential where
  prettyCookedOpt :: PrettyCookedOpts -> Credential -> DocCooked
prettyCookedOpt PrettyCookedOpts
opts (Api.ScriptCredential ScriptHash
vh) = DocCooked
"script" DocCooked -> DocCooked -> DocCooked
forall ann. Doc ann -> Doc ann -> Doc ann
<+> PrettyCookedHashOpts -> BuiltinByteString -> DocCooked
prettyHash (PrettyCookedOpts -> PrettyCookedHashOpts
pcOptHashes PrettyCookedOpts
opts) (ScriptHash -> BuiltinByteString
forall a. ToHash a => a -> BuiltinByteString
toHash ScriptHash
vh)
  prettyCookedOpt PrettyCookedOpts
opts (Api.PubKeyCredential PubKeyHash
pkh) = DocCooked
"pubkey" DocCooked -> DocCooked -> DocCooked
forall ann. Doc ann -> Doc ann -> Doc ann
<+> PrettyCookedOpts -> PubKeyHash -> DocCooked
forall a. PrettyCooked a => PrettyCookedOpts -> a -> DocCooked
prettyCookedOpt PrettyCookedOpts
opts PubKeyHash
pkh

instance PrettyCooked Api.Value where
  -- Example output:
  --
  -- > Value:
  -- >   - Lovelace: 45_000_000
  -- >   - Quick "hello": 3
  -- >   - #12bc3d "usertoken": 1
  --
  -- In case of an empty value (even though not an empty map):
  -- > Empty value
  prettyCookedOpt :: PrettyCookedOpts -> Value -> DocCooked
prettyCookedOpt PrettyCookedOpts
opts =
    [DocCooked] -> DocCooked
prettySingletons
      ([DocCooked] -> DocCooked)
-> (Value -> [DocCooked]) -> Value -> DocCooked
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ((CurrencySymbol, TokenName, Integer) -> DocCooked)
-> [(CurrencySymbol, TokenName, Integer)] -> [DocCooked]
forall a b. (a -> b) -> [a] -> [b]
map (CurrencySymbol, TokenName, Integer) -> DocCooked
prettySingletonValue
      ([(CurrencySymbol, TokenName, Integer)] -> [DocCooked])
-> (Value -> [(CurrencySymbol, TokenName, Integer)])
-> Value
-> [DocCooked]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ((CurrencySymbol, TokenName, Integer) -> Bool)
-> [(CurrencySymbol, TokenName, Integer)]
-> [(CurrencySymbol, TokenName, Integer)]
forall a. (a -> Bool) -> [a] -> [a]
filter (\(CurrencySymbol
_, TokenName
_, Integer
n) -> Integer
n Integer -> Integer -> Bool
forall a. Eq a => a -> a -> Bool
/= Integer
0)
      ([(CurrencySymbol, TokenName, Integer)]
 -> [(CurrencySymbol, TokenName, Integer)])
-> (Value -> [(CurrencySymbol, TokenName, Integer)])
-> Value
-> [(CurrencySymbol, TokenName, Integer)]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Value -> [(CurrencySymbol, TokenName, Integer)]
Script.flattenValue
    where
      prettySingletons :: [DocCooked] -> DocCooked
      prettySingletons :: [DocCooked] -> DocCooked
prettySingletons [] = DocCooked
"Empty value"
      prettySingletons [DocCooked
doc] = DocCooked
doc
      prettySingletons [DocCooked]
docs = DocCooked -> DocCooked -> [DocCooked] -> DocCooked
prettyItemize DocCooked
"Value:" DocCooked
"-" [DocCooked]
docs
      prettySingletonValue :: (Api.CurrencySymbol, Api.TokenName, Integer) -> DocCooked
      prettySingletonValue :: (CurrencySymbol, TokenName, Integer) -> DocCooked
prettySingletonValue (CurrencySymbol
symbol, TokenName
name, Integer
amount) =
        PrettyCookedOpts -> AssetClass -> DocCooked
forall a. PrettyCooked a => PrettyCookedOpts -> a -> DocCooked
prettyCookedOpt PrettyCookedOpts
opts ((CurrencySymbol, TokenName) -> AssetClass
Script.AssetClass (CurrencySymbol
symbol, TokenName
name)) DocCooked -> DocCooked -> DocCooked
forall a. Semigroup a => a -> a -> a
<> DocCooked
":" DocCooked -> DocCooked -> DocCooked
forall ann. Doc ann -> Doc ann -> Doc ann
<+> PrettyCookedOpts -> Integer -> DocCooked
forall a. PrettyCooked a => PrettyCookedOpts -> a -> DocCooked
prettyCookedOpt PrettyCookedOpts
opts Integer
amount

instance PrettyCooked Api.CurrencySymbol where
  prettyCookedOpt :: PrettyCookedOpts -> CurrencySymbol -> DocCooked
prettyCookedOpt PrettyCookedOpts
opts CurrencySymbol
symbol = PrettyCookedHashOpts -> BuiltinByteString -> DocCooked
prettyHash (PrettyCookedOpts -> PrettyCookedHashOpts
pcOptHashes PrettyCookedOpts
opts) (CurrencySymbol -> BuiltinByteString
forall a. ToHash a => a -> BuiltinByteString
toHash CurrencySymbol
symbol)

instance PrettyCooked Api.TokenName where
  prettyCookedOpt :: PrettyCookedOpts -> TokenName -> DocCooked
prettyCookedOpt PrettyCookedOpts
_ = TokenName -> DocCooked
forall a ann. Pretty a => a -> Doc ann
forall ann. TokenName -> Doc ann
PP.pretty

instance PrettyCooked Script.AssetClass where
  prettyCookedOpt :: PrettyCookedOpts -> AssetClass -> DocCooked
prettyCookedOpt PrettyCookedOpts
opts (Script.AssetClass (CurrencySymbol
symbol, TokenName
name)) =
    PrettyCookedOpts -> CurrencySymbol -> DocCooked
forall a. PrettyCooked a => PrettyCookedOpts -> a -> DocCooked
prettyCookedOpt PrettyCookedOpts
opts CurrencySymbol
symbol
      DocCooked -> DocCooked -> DocCooked
forall ann. Doc ann -> Doc ann -> Doc ann
<+> if CurrencySymbol
symbol CurrencySymbol -> CurrencySymbol -> Bool
forall a. Eq a => a -> a -> Bool
/= BuiltinByteString -> CurrencySymbol
Api.CurrencySymbol BuiltinByteString
""
        then PrettyCookedOpts -> TokenName -> DocCooked
forall a. PrettyCooked a => PrettyCookedOpts -> a -> DocCooked
prettyCookedOpt PrettyCookedOpts
opts TokenName
name
        else DocCooked
forall a. Monoid a => a
mempty

instance PrettyCooked Ledger.ValidationPhase where
  prettyCookedOpt :: PrettyCookedOpts -> ValidationPhase -> DocCooked
prettyCookedOpt PrettyCookedOpts
_ ValidationPhase
Ledger.Phase1 = DocCooked
"Phase 1"
  prettyCookedOpt PrettyCookedOpts
_ ValidationPhase
Ledger.Phase2 = DocCooked
"Phase 2"

instance PrettyCooked Ledger.ValidationError where
  prettyCookedOpt :: PrettyCookedOpts -> ValidationError -> DocCooked
prettyCookedOpt PrettyCookedOpts
opts (Ledger.TxOutRefNotFound TxIn
txIn) = DocCooked
"TxOutRef not found" DocCooked -> DocCooked -> DocCooked
forall ann. Doc ann -> Doc ann -> Doc ann
<+> PrettyCookedOpts -> TxOutRef -> DocCooked
forall a. PrettyCooked a => PrettyCookedOpts -> a -> DocCooked
prettyCookedOpt PrettyCookedOpts
opts (TxIn -> TxOutRef
Ledger.fromCardanoTxIn TxIn
txIn)
  prettyCookedOpt PrettyCookedOpts
opts (Ledger.ScriptFailure ScriptError
scriptError) = DocCooked
"Script failure" DocCooked -> DocCooked -> DocCooked
forall ann. Doc ann -> Doc ann -> Doc ann
<+> PrettyCookedOpts -> ScriptError -> DocCooked
forall a. PrettyCooked a => PrettyCookedOpts -> a -> DocCooked
prettyCookedOpt PrettyCookedOpts
opts ScriptError
scriptError
  prettyCookedOpt PrettyCookedOpts
_ (Ledger.CardanoLedgerValidationError Text
text) = DocCooked
"Cardano ledger validation error " DocCooked -> DocCooked -> DocCooked
forall ann. Doc ann -> Doc ann -> Doc ann
<+> Text -> DocCooked
forall ann. Text -> Doc ann
forall a ann. Pretty a => a -> Doc ann
PP.pretty Text
text
  prettyCookedOpt PrettyCookedOpts
_ ValidationError
Ledger.MaxCollateralInputsExceeded = DocCooked
"Max collateral inputs exceeded"

instance PrettyCooked Ledger.ScriptError where
  prettyCookedOpt :: PrettyCookedOpts -> ScriptError -> DocCooked
prettyCookedOpt PrettyCookedOpts
_ (Ledger.EvaluationError [Text]
text String
string) = DocCooked
"Evaluation error" DocCooked -> DocCooked -> DocCooked
forall ann. Doc ann -> Doc ann -> Doc ann
<+> [Text] -> DocCooked
forall ann. [Text] -> Doc ann
forall a ann. Pretty a => a -> Doc ann
PP.pretty [Text]
text DocCooked -> DocCooked -> DocCooked
forall ann. Doc ann -> Doc ann -> Doc ann
<+> String -> DocCooked
forall ann. String -> Doc ann
forall a ann. Pretty a => a -> Doc ann
PP.pretty String
string
  prettyCookedOpt PrettyCookedOpts
_ (Ledger.EvaluationException String
string1 String
string2) = DocCooked
"Evaluation exception" DocCooked -> DocCooked -> DocCooked
forall ann. Doc ann -> Doc ann -> Doc ann
<+> String -> DocCooked
forall ann. String -> Doc ann
forall a ann. Pretty a => a -> Doc ann
PP.pretty String
string1 DocCooked -> DocCooked -> DocCooked
forall ann. Doc ann -> Doc ann -> Doc ann
<+> String -> DocCooked
forall ann. String -> Doc ann
forall a ann. Pretty a => a -> Doc ann
PP.pretty String
string2

instance PrettyCooked Api.POSIXTime where
  prettyCookedOpt :: PrettyCookedOpts -> POSIXTime -> DocCooked
prettyCookedOpt PrettyCookedOpts
opts (Api.POSIXTime Integer
n) = DocCooked
"POSIXTime" DocCooked -> DocCooked -> DocCooked
forall ann. Doc ann -> Doc ann -> Doc ann
<+> PrettyCookedOpts -> Integer -> DocCooked
forall a. PrettyCooked a => PrettyCookedOpts -> a -> DocCooked
prettyCookedOpt PrettyCookedOpts
opts Integer
n

instance PrettyCooked Ledger.ScriptHash where
  prettyCookedOpt :: PrettyCookedOpts -> ScriptHash -> DocCooked
prettyCookedOpt PrettyCookedOpts
opts = PrettyCookedHashOpts -> BuiltinByteString -> DocCooked
prettyHash (PrettyCookedOpts -> PrettyCookedHashOpts
pcOptHashes PrettyCookedOpts
opts) (BuiltinByteString -> DocCooked)
-> (ScriptHash -> BuiltinByteString) -> ScriptHash -> DocCooked
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ScriptHash -> BuiltinByteString
forall a. ToHash a => a -> BuiltinByteString
toHash

instance (PrettyCooked a) => PrettyCooked [a] where
  prettyCookedOpt :: PrettyCookedOpts -> [a] -> DocCooked
prettyCookedOpt PrettyCookedOpts
opts = DocCooked -> [DocCooked] -> DocCooked
prettyItemizeNoTitle DocCooked
"-" ([DocCooked] -> DocCooked)
-> ([a] -> [DocCooked]) -> [a] -> DocCooked
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (a -> DocCooked) -> [a] -> [DocCooked]
forall a b. (a -> b) -> [a] -> [b]
map (PrettyCookedOpts -> a -> DocCooked
forall a. PrettyCooked a => PrettyCookedOpts -> a -> DocCooked
prettyCookedOpt PrettyCookedOpts
opts)

instance PrettyCooked Int where
  prettyCookedOpt :: PrettyCookedOpts -> Int -> DocCooked
prettyCookedOpt PrettyCookedOpts
_ = Int -> DocCooked
forall ann. Int -> Doc ann
forall a ann. Pretty a => a -> Doc ann
PP.pretty

instance PrettyCooked Integer where
  prettyCookedOpt :: PrettyCookedOpts -> Integer -> DocCooked
prettyCookedOpt PrettyCookedOpts
opts =
    if PrettyCookedOpts -> Bool
pcOptNumericUnderscores PrettyCookedOpts
opts
      then Integer -> DocCooked
prettyNumericUnderscore
      else Integer -> DocCooked
forall ann. Integer -> Doc ann
forall a ann. Pretty a => a -> Doc ann
PP.pretty
    where
      -- prettyNumericUnderscore 23798423723
      -- 23_798_423_723
      prettyNumericUnderscore :: Integer -> DocCooked
      prettyNumericUnderscore :: Integer -> DocCooked
prettyNumericUnderscore Integer
i
        | Integer
0 Integer -> Integer -> Bool
forall a. Eq a => a -> a -> Bool
== Integer
i = DocCooked
"0"
        | Integer
i Integer -> Integer -> Bool
forall a. Ord a => a -> a -> Bool
> Integer
0 = DocCooked -> Integer -> Integer -> DocCooked
psnTerm DocCooked
"" Integer
0 Integer
i
        | Bool
otherwise = DocCooked
"-" DocCooked -> DocCooked -> DocCooked
forall a. Semigroup a => a -> a -> a
<> DocCooked -> Integer -> Integer -> DocCooked
psnTerm DocCooked
"" Integer
0 (-Integer
i)
        where
          psnTerm :: DocCooked -> Integer -> Integer -> DocCooked
          psnTerm :: DocCooked -> Integer -> Integer -> DocCooked
psnTerm DocCooked
acc Integer
_ Integer
0 = DocCooked
acc
          psnTerm DocCooked
acc Integer
3 Integer
nb = DocCooked -> Integer -> Integer -> DocCooked
psnTerm (Integer -> DocCooked
forall ann. Integer -> Doc ann
forall a ann. Pretty a => a -> Doc ann
PP.pretty (Integer
nb Integer -> Integer -> Integer
forall a. Integral a => a -> a -> a
`mod` Integer
10) DocCooked -> DocCooked -> DocCooked
forall a. Semigroup a => a -> a -> a
<> DocCooked
"_" DocCooked -> DocCooked -> DocCooked
forall a. Semigroup a => a -> a -> a
<> DocCooked
acc) Integer
1 (Integer
nb Integer -> Integer -> Integer
forall a. Integral a => a -> a -> a
`div` Integer
10)
          psnTerm DocCooked
acc Integer
n Integer
nb = DocCooked -> Integer -> Integer -> DocCooked
psnTerm (Integer -> DocCooked
forall ann. Integer -> Doc ann
forall a ann. Pretty a => a -> Doc ann
PP.pretty (Integer
nb Integer -> Integer -> Integer
forall a. Integral a => a -> a -> a
`mod` Integer
10) DocCooked -> DocCooked -> DocCooked
forall a. Semigroup a => a -> a -> a
<> DocCooked
acc) (Integer
n Integer -> Integer -> Integer
forall a. Num a => a -> a -> a
+ Integer
1) (Integer
nb Integer -> Integer -> Integer
forall a. Integral a => a -> a -> a
`div` Integer
10)

instance PrettyCooked Bool where
  prettyCookedOpt :: PrettyCookedOpts -> Bool -> DocCooked
prettyCookedOpt PrettyCookedOpts
_ = Bool -> DocCooked
forall ann. Bool -> Doc ann
forall a ann. Pretty a => a -> Doc ann
PP.pretty

instance PrettyCooked () where
  prettyCookedOpt :: PrettyCookedOpts -> () -> DocCooked
prettyCookedOpt PrettyCookedOpts
_ = () -> DocCooked
forall ann. () -> Doc ann
forall a ann. Pretty a => a -> Doc ann
PP.pretty

instance PrettyCooked Api.BuiltinData where
  prettyCookedOpt :: PrettyCookedOpts -> BuiltinData -> DocCooked
prettyCookedOpt PrettyCookedOpts
_ = BuiltinData -> DocCooked
forall a ann. Pretty a => a -> Doc ann
forall ann. BuiltinData -> Doc ann
PP.pretty

instance PrettyCooked Rational where
  prettyCookedOpt :: PrettyCookedOpts -> Rational -> DocCooked
prettyCookedOpt PrettyCookedOpts
opts Rational
q = DocCooked
"(" DocCooked -> DocCooked -> DocCooked
forall ann. Doc ann -> Doc ann -> Doc ann
<+> PrettyCookedOpts -> Integer -> DocCooked
forall a. PrettyCooked a => PrettyCookedOpts -> a -> DocCooked
prettyCookedOpt PrettyCookedOpts
opts (Rational -> Integer
forall a. Ratio a -> a
numerator Rational
q) DocCooked -> DocCooked -> DocCooked
forall ann. Doc ann -> Doc ann -> Doc ann
<+> DocCooked
"/" DocCooked -> DocCooked -> DocCooked
forall ann. Doc ann -> Doc ann -> Doc ann
<+> PrettyCookedOpts -> Integer -> DocCooked
forall a. PrettyCooked a => PrettyCookedOpts -> a -> DocCooked
prettyCookedOpt PrettyCookedOpts
opts (Rational -> Integer
forall a. Ratio a -> a
denominator Rational
q) DocCooked -> DocCooked -> DocCooked
forall ann. Doc ann -> Doc ann -> Doc ann
<+> DocCooked
")"