{-# LANGUAGE DataKinds #-}
{-# LANGUAGE OverloadedStrings #-}
{-# LANGUAGE DerivingVia #-}
{-# LANGUAGE GeneralizedNewtypeDeriving #-}
{-# LANGUAGE ScopedTypeVariables #-}
{-# LANGUAGE StandaloneDeriving #-}
{-# LANGUAGE StrictData #-}
{-# LANGUAGE TypeApplications #-}
{-# LANGUAGE TypeFamilies #-}
{-# LANGUAGE TypeOperators #-}
{-# LANGUAGE UndecidableInstances #-}

{-|
  Module      : Data.Text.Entity
  Copyright   : © Hécate Moonlight, 2021
  License     : MIT
  Maintainer  : hecate@glitchbra.in
  Stability   : stable

  Use 'display' to produce user-facing text

-}
module Data.Text.Display
  ( -- * Documentation
    display
  , Display(..)
  , -- * Deriving your instance automatically
    ShowInstance(..)
  , OpaqueInstance(..)
  , -- * Writing your instance by hand
    displayParen
  -- * Design choices
  -- $designChoices
  ) where

import Control.Exception hiding (TypeError)
import Data.ByteString
import Data.Int
import Data.Kind
import Data.List.NonEmpty
import Data.Text (Text)
import Data.Text.Lazy.Builder (Builder)
import Data.Word
import GHC.Show (showLitString)
import GHC.TypeLits
import qualified Data.ByteString.Lazy as BL
import qualified Data.Text.Lazy.Builder as TB
import qualified Data.Text.Lazy.Builder.Int as TB
import qualified Data.Text.Lazy.Builder.RealFloat as TB
import qualified Data.Text.Lazy as TL
import Data.Proxy

-- | A typeclass for user-facing output.
--
-- @since 0.0.1.0
class Display a where
  {-# MINIMAL displayBuilder | displayPrec #-}
  -- | Implement this method to describe how to convert your value to 'Builder'.
  displayBuilder :: a -> Builder
  displayBuilder = Int -> a -> Builder
forall a. Display a => Int -> a -> Builder
displayPrec Int
0

  -- | The method 'displayList' is provided to allow for a specialised
  -- way to render lists of a certain value.
  -- This is used to render the list of 'Char' as a string of characters
  -- enclosed in double quotes, rather than between square brackets and
  -- separated by commas.
  --
  -- === Example
  --
  -- > instance Display Char where
  -- >   displayBuilder '\'' = "'\\''"
  -- >   displayBuilder c = "'" <> TB.singleton c <> "\'"
  -- >   -- 'displayList' is overloaded, so that when the @Display [a]@ instance calls 'displayList',
  -- >   -- we end up with a nice string enclosed between double quotes.
  -- >   displayList cs = TB.fromString $ "\"" <> showLitString cs "\""
  --
  -- > instance Display a => Display [a] where
  -- >   -- In this instance, 'displayBuilder' is defined in terms of 'displayList', which for most types
  -- >   -- is defined as the default written in the class declaration.
  -- >   -- But when a ~ Char, there is an explicit implementation that is selected instead, which
  -- >   -- provides the rendering of the character string between double quotes.
  -- >   displayBuilder = displayList
  --
  -- ==== How implementations are selected
  --
  -- > displayBuilder ([1,2,3] :: [Int])
  -- > → displayBuilder @[Int] = displayBuilderList @Int
  -- > → Default `displayList`
  -- >
  -- > displayBuilder ("abc" :: [Char])
  -- > → displayBuilder @[Char] = displayBuilderList @Char
  -- > → Custom `displayList`
  displayList :: [a] -> Builder
  displayList [] = Builder
"[]"
  displayList (a
x:[a]
xs) = [a] -> Builder -> Builder
displayList' [a]
xs (Builder
"[" Builder -> Builder -> Builder
forall a. Semigroup a => a -> a -> a
<> a -> Builder
forall a. Display a => a -> Builder
displayBuilder a
x)
    where
      displayList' :: [a] -> Builder -> Builder
      displayList' :: [a] -> Builder -> Builder
displayList' [] Builder
acc     = Builder
acc Builder -> Builder -> Builder
forall a. Semigroup a => a -> a -> a
<> Builder
"]"
      displayList' (a
y:[a]
ys) Builder
acc = [a] -> Builder -> Builder
displayList' [a]
ys (Builder
acc Builder -> Builder -> Builder
forall a. Semigroup a => a -> a -> a
<> Builder
"," Builder -> Builder -> Builder
forall a. Semigroup a => a -> a -> a
<> a -> Builder
forall a. Display a => a -> Builder
displayBuilder a
y)

  -- | The method 'displayPrec' allows you to write instances that
  -- require nesting. The precedence parameter can be thought of as a
  -- suggestion coming from the surrounding context for how tightly to bind. If the precedence
  -- parameter is higher than the precedence of the operator (or constructor, function, etc.)
  -- being displayed, then that suggests that the output will need to be surrounded in parentheses
  -- in order to bind tightly enough (see 'displayParen').
  --
  -- For example, if an operator constructor is being displayed, then the precedence requirement
  -- for its arguments will be the precedence of the operator. Meaning, if the argument
  -- binds looser than the surrounding operator, then it will require parentheses.
  --
  -- Note that function/constructor application has an effective precedence of 10.
  --
  -- === Examples
  --
  -- > instance Display a => Display (Maybe a) where
  -- >   -- In this instance, we define 'displayPrec' rather than 'displayBuilder' as we need to decide
  -- >   -- whether or not to surround ourselves in parentheses based on the surrounding context.
  -- >   -- If the precedence parameter is higher than 10 (the precedence of constructor application)
  -- >   -- then we indeed need to surround ourselves in parentheses to avoid malformed outputs
  -- >   -- such as @Just Just 5@.
  -- >   -- We then set the precedence parameter of the inner 'displayPrec' to 11, as even
  -- >   -- constructor application is not strong enough to avoid parentheses.
  -- >   displayPrec _ Nothing = "Nothing"
  -- >   displayPrec prec (Just a) = displayParen (prec > 10) $ "Just " <> displayPrec 11 a
  --
  -- > data Pair a b = a :*: b
  -- > infix 5 :*: -- arbitrary choice of precedence
  -- > instance (Display a, Display b) => Display (Pair a b) where
  -- >   displayPrec prec (a :*: b) = displayParen (prec > 5) $ displayPrec 6 a <> " :*: " <> displayPrec 6 b
  displayPrec
    :: Int -- ^ The precedence level passed in by the surrounding context
    -> a
    -> Builder
  displayPrec Int
_ = a -> Builder
forall a. Display a => a -> Builder
displayBuilder


-- | Convert a value to a readable 'Text'.
--
-- === Examples
-- >>> display 3
-- "3"
--
-- >>> display True
-- "True"
--
-- @since 0.0.1.0
display :: Display a => a -> Text
display :: a -> Text
display a
a = Text -> Text
TL.toStrict (Text -> Text) -> Text -> Text
forall a b. (a -> b) -> a -> b
$ Builder -> Text
TB.toLazyText (Builder -> Text) -> Builder -> Text
forall a b. (a -> b) -> a -> b
$ a -> Builder
forall a. Display a => a -> Builder
displayBuilder a
a

-- | 🚫 You should not try to display functions!
--
-- 💡 Write a 'newtype' wrapper that represents your domain more accurately.
--    If you are not consciously trying to use 'display' on a function,
--    make sure that you are not missing an argument somewhere.
--
-- @since 0.0.1.0
instance CannotDisplayBareFunctions => Display (a -> b) where
  displayBuilder :: (a -> b) -> Builder
displayBuilder = (a -> b) -> Builder
forall a. HasCallStack => a
undefined

-- | @since 0.0.1.0
type family CannotDisplayBareFunctions :: Constraint where
  CannotDisplayBareFunctions = TypeError
    ( 'Text "🚫 You should not try to display functions!" ':$$:
      'Text "💡 Write a 'newtype' wrapper that represents your domain more accurately." ':$$:
      'Text "   If you are not consciously trying to use `display` on a function," ':$$:
      'Text "   make sure that you are not missing an argument somewhere."
    )

-- | 🚫 You should not try to display strict ByteStrings!
--
-- 💡 Always provide an explicit encoding.
-- Use 'Data.Text.Encoding.decodeUtf8'' or 'Data.Text.Encoding.decodeUtf8With' to convert from UTF-8
--
-- @since 0.0.1.0
instance CannotDisplayByteStrings => Display ByteString where
  displayBuilder :: ByteString -> Builder
displayBuilder = ByteString -> Builder
forall a. HasCallStack => a
undefined

-- | 🚫 You should not try to display lazy ByteStrings!
--
-- 💡 Always provide an explicit encoding.
-- Use 'Data.Text.Encoding.decodeUtf8'' or 'Data.Text.Encoding.decodeUtf8With' to convert from UTF-8
--
-- @since 0.0.1.0
instance CannotDisplayByteStrings => Display BL.ByteString where
  displayBuilder :: ByteString -> Builder
displayBuilder = ByteString -> Builder
forall a. HasCallStack => a
undefined

type family CannotDisplayByteStrings :: Constraint where
  CannotDisplayByteStrings = TypeError
    ( 'Text "🚫 You should not try to display ByteStrings!" ':$$:
      'Text "💡 Always provide an explicit encoding" ':$$:
      'Text     "Use 'Data.Text.Encoding.decodeUtf8'' or 'Data.Text.Encoding.decodeUtf8With' to convert from UTF-8"
    )

-- | A utility function that surrounds the given 'Builder' with parentheses when the Bool parameter is True.
-- Useful for writing instances that may require nesting. See the 'displayPrec' documentation for more
-- information.
--
-- @since 0.0.1.0
displayParen :: Bool -> Builder -> Builder
displayParen :: Bool -> Builder -> Builder
displayParen Bool
b Builder
txt = if Bool
b then Builder
"(" Builder -> Builder -> Builder
forall a. Semigroup a => a -> a -> a
<> Builder
txt Builder -> Builder -> Builder
forall a. Semigroup a => a -> a -> a
<> Builder
")" else Builder
txt

-- | This wrapper allows you to create an opaque instance for your type,
-- useful for redacting sensitive content like tokens or passwords.
--
-- === Example
--
-- > data UserToken = UserToken UUID
-- >  deriving Display
-- >    via (OpaqueInstance "[REDACTED]" UserToken)
--
-- > display $ UserToken "7a01d2ce-31ff-11ec-8c10-5405db82c3cd"
-- > "[REDACTED]"
--
-- @since 0.0.1.0
newtype OpaqueInstance (str :: Symbol) (a :: Type) = Opaque a

-- | This wrapper allows you to create an opaque instance for your type,
-- useful for redacting sensitive content like tokens or passwords.
--
-- @since 0.0.1.0
instance KnownSymbol str => Display (OpaqueInstance str a) where
  displayBuilder :: OpaqueInstance str a -> Builder
displayBuilder OpaqueInstance str a
_ = String -> Builder
TB.fromString (String -> Builder) -> String -> Builder
forall a b. (a -> b) -> a -> b
$ Proxy str -> String
forall (n :: Symbol) (proxy :: Symbol -> *).
KnownSymbol n =>
proxy n -> String
symbolVal (Proxy str
forall k (t :: k). Proxy t
Proxy @str)

-- | This wrapper allows you to rely on a pre-existing 'Show' instance in order to
-- derive 'Display' from it.
--
-- === Example
--
-- > data AutomaticallyDerived = AD
-- >  -- We derive 'Show'
-- >  deriving stock Show
-- >  -- We take advantage of the 'Show' instance to derive 'Display' from it
-- >  deriving Display
-- >    via (ShowInstance AutomaticallyDerived)
--
-- @since 0.0.1.0
newtype ShowInstance (a :: Type)
  = ShowInstance a
  deriving newtype
    ( Show -- ^ @since 0.0.1.0
    )

-- | This wrapper allows you to rely on a pre-existing 'Show' instance in order to derive 'Display' from it.
--
-- @since 0.0.1.0
instance Show e => Display (ShowInstance e) where
  displayBuilder :: ShowInstance e -> Builder
displayBuilder ShowInstance e
s = String -> Builder
TB.fromString (String -> Builder) -> String -> Builder
forall a b. (a -> b) -> a -> b
$ ShowInstance e -> String
forall a. Show a => a -> String
show ShowInstance e
s

-- @since 0.0.1.0
newtype DisplayDecimal e
  = DisplayDecimal e
  deriving newtype
    (Enum (DisplayDecimal e)
Real (DisplayDecimal e)
Real (DisplayDecimal e)
-> Enum (DisplayDecimal e)
-> (DisplayDecimal e -> DisplayDecimal e -> DisplayDecimal e)
-> (DisplayDecimal e -> DisplayDecimal e -> DisplayDecimal e)
-> (DisplayDecimal e -> DisplayDecimal e -> DisplayDecimal e)
-> (DisplayDecimal e -> DisplayDecimal e -> DisplayDecimal e)
-> (DisplayDecimal e
    -> DisplayDecimal e -> (DisplayDecimal e, DisplayDecimal e))
-> (DisplayDecimal e
    -> DisplayDecimal e -> (DisplayDecimal e, DisplayDecimal e))
-> (DisplayDecimal e -> Integer)
-> Integral (DisplayDecimal e)
DisplayDecimal e -> Integer
DisplayDecimal e
-> DisplayDecimal e -> (DisplayDecimal e, DisplayDecimal e)
DisplayDecimal e -> DisplayDecimal e -> DisplayDecimal e
forall e. Integral e => Enum (DisplayDecimal e)
forall e. Integral e => Real (DisplayDecimal e)
forall e. Integral e => DisplayDecimal e -> Integer
forall e.
Integral e =>
DisplayDecimal e
-> DisplayDecimal e -> (DisplayDecimal e, DisplayDecimal e)
forall e.
Integral e =>
DisplayDecimal e -> DisplayDecimal e -> DisplayDecimal e
forall a.
Real a
-> Enum a
-> (a -> a -> a)
-> (a -> a -> a)
-> (a -> a -> a)
-> (a -> a -> a)
-> (a -> a -> (a, a))
-> (a -> a -> (a, a))
-> (a -> Integer)
-> Integral a
toInteger :: DisplayDecimal e -> Integer
$ctoInteger :: forall e. Integral e => DisplayDecimal e -> Integer
divMod :: DisplayDecimal e
-> DisplayDecimal e -> (DisplayDecimal e, DisplayDecimal e)
$cdivMod :: forall e.
Integral e =>
DisplayDecimal e
-> DisplayDecimal e -> (DisplayDecimal e, DisplayDecimal e)
quotRem :: DisplayDecimal e
-> DisplayDecimal e -> (DisplayDecimal e, DisplayDecimal e)
$cquotRem :: forall e.
Integral e =>
DisplayDecimal e
-> DisplayDecimal e -> (DisplayDecimal e, DisplayDecimal e)
mod :: DisplayDecimal e -> DisplayDecimal e -> DisplayDecimal e
$cmod :: forall e.
Integral e =>
DisplayDecimal e -> DisplayDecimal e -> DisplayDecimal e
div :: DisplayDecimal e -> DisplayDecimal e -> DisplayDecimal e
$cdiv :: forall e.
Integral e =>
DisplayDecimal e -> DisplayDecimal e -> DisplayDecimal e
rem :: DisplayDecimal e -> DisplayDecimal e -> DisplayDecimal e
$crem :: forall e.
Integral e =>
DisplayDecimal e -> DisplayDecimal e -> DisplayDecimal e
quot :: DisplayDecimal e -> DisplayDecimal e -> DisplayDecimal e
$cquot :: forall e.
Integral e =>
DisplayDecimal e -> DisplayDecimal e -> DisplayDecimal e
$cp2Integral :: forall e. Integral e => Enum (DisplayDecimal e)
$cp1Integral :: forall e. Integral e => Real (DisplayDecimal e)
Integral, Num (DisplayDecimal e)
Ord (DisplayDecimal e)
Num (DisplayDecimal e)
-> Ord (DisplayDecimal e)
-> (DisplayDecimal e -> Rational)
-> Real (DisplayDecimal e)
DisplayDecimal e -> Rational
forall a. Num a -> Ord a -> (a -> Rational) -> Real a
forall e. Real e => Num (DisplayDecimal e)
forall e. Real e => Ord (DisplayDecimal e)
forall e. Real e => DisplayDecimal e -> Rational
toRational :: DisplayDecimal e -> Rational
$ctoRational :: forall e. Real e => DisplayDecimal e -> Rational
$cp2Real :: forall e. Real e => Ord (DisplayDecimal e)
$cp1Real :: forall e. Real e => Num (DisplayDecimal e)
Real, Int -> DisplayDecimal e
DisplayDecimal e -> Int
DisplayDecimal e -> [DisplayDecimal e]
DisplayDecimal e -> DisplayDecimal e
DisplayDecimal e -> DisplayDecimal e -> [DisplayDecimal e]
DisplayDecimal e
-> DisplayDecimal e -> DisplayDecimal e -> [DisplayDecimal e]
(DisplayDecimal e -> DisplayDecimal e)
-> (DisplayDecimal e -> DisplayDecimal e)
-> (Int -> DisplayDecimal e)
-> (DisplayDecimal e -> Int)
-> (DisplayDecimal e -> [DisplayDecimal e])
-> (DisplayDecimal e -> DisplayDecimal e -> [DisplayDecimal e])
-> (DisplayDecimal e -> DisplayDecimal e -> [DisplayDecimal e])
-> (DisplayDecimal e
    -> DisplayDecimal e -> DisplayDecimal e -> [DisplayDecimal e])
-> Enum (DisplayDecimal e)
forall e. Enum e => Int -> DisplayDecimal e
forall e. Enum e => DisplayDecimal e -> Int
forall e. Enum e => DisplayDecimal e -> [DisplayDecimal e]
forall e. Enum e => DisplayDecimal e -> DisplayDecimal e
forall e.
Enum e =>
DisplayDecimal e -> DisplayDecimal e -> [DisplayDecimal e]
forall e.
Enum e =>
DisplayDecimal e
-> DisplayDecimal e -> DisplayDecimal e -> [DisplayDecimal e]
forall a.
(a -> a)
-> (a -> a)
-> (Int -> a)
-> (a -> Int)
-> (a -> [a])
-> (a -> a -> [a])
-> (a -> a -> [a])
-> (a -> a -> a -> [a])
-> Enum a
enumFromThenTo :: DisplayDecimal e
-> DisplayDecimal e -> DisplayDecimal e -> [DisplayDecimal e]
$cenumFromThenTo :: forall e.
Enum e =>
DisplayDecimal e
-> DisplayDecimal e -> DisplayDecimal e -> [DisplayDecimal e]
enumFromTo :: DisplayDecimal e -> DisplayDecimal e -> [DisplayDecimal e]
$cenumFromTo :: forall e.
Enum e =>
DisplayDecimal e -> DisplayDecimal e -> [DisplayDecimal e]
enumFromThen :: DisplayDecimal e -> DisplayDecimal e -> [DisplayDecimal e]
$cenumFromThen :: forall e.
Enum e =>
DisplayDecimal e -> DisplayDecimal e -> [DisplayDecimal e]
enumFrom :: DisplayDecimal e -> [DisplayDecimal e]
$cenumFrom :: forall e. Enum e => DisplayDecimal e -> [DisplayDecimal e]
fromEnum :: DisplayDecimal e -> Int
$cfromEnum :: forall e. Enum e => DisplayDecimal e -> Int
toEnum :: Int -> DisplayDecimal e
$ctoEnum :: forall e. Enum e => Int -> DisplayDecimal e
pred :: DisplayDecimal e -> DisplayDecimal e
$cpred :: forall e. Enum e => DisplayDecimal e -> DisplayDecimal e
succ :: DisplayDecimal e -> DisplayDecimal e
$csucc :: forall e. Enum e => DisplayDecimal e -> DisplayDecimal e
Enum, Eq (DisplayDecimal e)
Eq (DisplayDecimal e)
-> (DisplayDecimal e -> DisplayDecimal e -> Ordering)
-> (DisplayDecimal e -> DisplayDecimal e -> Bool)
-> (DisplayDecimal e -> DisplayDecimal e -> Bool)
-> (DisplayDecimal e -> DisplayDecimal e -> Bool)
-> (DisplayDecimal e -> DisplayDecimal e -> Bool)
-> (DisplayDecimal e -> DisplayDecimal e -> DisplayDecimal e)
-> (DisplayDecimal e -> DisplayDecimal e -> DisplayDecimal e)
-> Ord (DisplayDecimal e)
DisplayDecimal e -> DisplayDecimal e -> Bool
DisplayDecimal e -> DisplayDecimal e -> Ordering
DisplayDecimal e -> DisplayDecimal e -> DisplayDecimal e
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
forall e. Ord e => Eq (DisplayDecimal e)
forall e. Ord e => DisplayDecimal e -> DisplayDecimal e -> Bool
forall e. Ord e => DisplayDecimal e -> DisplayDecimal e -> Ordering
forall e.
Ord e =>
DisplayDecimal e -> DisplayDecimal e -> DisplayDecimal e
min :: DisplayDecimal e -> DisplayDecimal e -> DisplayDecimal e
$cmin :: forall e.
Ord e =>
DisplayDecimal e -> DisplayDecimal e -> DisplayDecimal e
max :: DisplayDecimal e -> DisplayDecimal e -> DisplayDecimal e
$cmax :: forall e.
Ord e =>
DisplayDecimal e -> DisplayDecimal e -> DisplayDecimal e
>= :: DisplayDecimal e -> DisplayDecimal e -> Bool
$c>= :: forall e. Ord e => DisplayDecimal e -> DisplayDecimal e -> Bool
> :: DisplayDecimal e -> DisplayDecimal e -> Bool
$c> :: forall e. Ord e => DisplayDecimal e -> DisplayDecimal e -> Bool
<= :: DisplayDecimal e -> DisplayDecimal e -> Bool
$c<= :: forall e. Ord e => DisplayDecimal e -> DisplayDecimal e -> Bool
< :: DisplayDecimal e -> DisplayDecimal e -> Bool
$c< :: forall e. Ord e => DisplayDecimal e -> DisplayDecimal e -> Bool
compare :: DisplayDecimal e -> DisplayDecimal e -> Ordering
$ccompare :: forall e. Ord e => DisplayDecimal e -> DisplayDecimal e -> Ordering
$cp1Ord :: forall e. Ord e => Eq (DisplayDecimal e)
Ord, Integer -> DisplayDecimal e
DisplayDecimal e -> DisplayDecimal e
DisplayDecimal e -> DisplayDecimal e -> DisplayDecimal e
(DisplayDecimal e -> DisplayDecimal e -> DisplayDecimal e)
-> (DisplayDecimal e -> DisplayDecimal e -> DisplayDecimal e)
-> (DisplayDecimal e -> DisplayDecimal e -> DisplayDecimal e)
-> (DisplayDecimal e -> DisplayDecimal e)
-> (DisplayDecimal e -> DisplayDecimal e)
-> (DisplayDecimal e -> DisplayDecimal e)
-> (Integer -> DisplayDecimal e)
-> Num (DisplayDecimal e)
forall e. Num e => Integer -> DisplayDecimal e
forall e. Num e => DisplayDecimal e -> DisplayDecimal e
forall e.
Num e =>
DisplayDecimal e -> DisplayDecimal e -> DisplayDecimal e
forall a.
(a -> a -> a)
-> (a -> a -> a)
-> (a -> a -> a)
-> (a -> a)
-> (a -> a)
-> (a -> a)
-> (Integer -> a)
-> Num a
fromInteger :: Integer -> DisplayDecimal e
$cfromInteger :: forall e. Num e => Integer -> DisplayDecimal e
signum :: DisplayDecimal e -> DisplayDecimal e
$csignum :: forall e. Num e => DisplayDecimal e -> DisplayDecimal e
abs :: DisplayDecimal e -> DisplayDecimal e
$cabs :: forall e. Num e => DisplayDecimal e -> DisplayDecimal e
negate :: DisplayDecimal e -> DisplayDecimal e
$cnegate :: forall e. Num e => DisplayDecimal e -> DisplayDecimal e
* :: DisplayDecimal e -> DisplayDecimal e -> DisplayDecimal e
$c* :: forall e.
Num e =>
DisplayDecimal e -> DisplayDecimal e -> DisplayDecimal e
- :: DisplayDecimal e -> DisplayDecimal e -> DisplayDecimal e
$c- :: forall e.
Num e =>
DisplayDecimal e -> DisplayDecimal e -> DisplayDecimal e
+ :: DisplayDecimal e -> DisplayDecimal e -> DisplayDecimal e
$c+ :: forall e.
Num e =>
DisplayDecimal e -> DisplayDecimal e -> DisplayDecimal e
Num, DisplayDecimal e -> DisplayDecimal e -> Bool
(DisplayDecimal e -> DisplayDecimal e -> Bool)
-> (DisplayDecimal e -> DisplayDecimal e -> Bool)
-> Eq (DisplayDecimal e)
forall e. Eq e => DisplayDecimal e -> DisplayDecimal e -> Bool
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: DisplayDecimal e -> DisplayDecimal e -> Bool
$c/= :: forall e. Eq e => DisplayDecimal e -> DisplayDecimal e -> Bool
== :: DisplayDecimal e -> DisplayDecimal e -> Bool
$c== :: forall e. Eq e => DisplayDecimal e -> DisplayDecimal e -> Bool
Eq)

-- @since 0.0.1.0
instance Integral e => Display (DisplayDecimal e) where
  displayBuilder :: DisplayDecimal e -> Builder
displayBuilder = DisplayDecimal e -> Builder
forall a. Integral a => a -> Builder
TB.decimal

-- @since 0.0.1.0
newtype DisplayRealFloat e
  = DisplayRealFloat e
  deriving newtype
    (Floating (DisplayRealFloat e)
RealFrac (DisplayRealFloat e)
RealFrac (DisplayRealFloat e)
-> Floating (DisplayRealFloat e)
-> (DisplayRealFloat e -> Integer)
-> (DisplayRealFloat e -> Int)
-> (DisplayRealFloat e -> (Int, Int))
-> (DisplayRealFloat e -> (Integer, Int))
-> (Integer -> Int -> DisplayRealFloat e)
-> (DisplayRealFloat e -> Int)
-> (DisplayRealFloat e -> DisplayRealFloat e)
-> (Int -> DisplayRealFloat e -> DisplayRealFloat e)
-> (DisplayRealFloat e -> Bool)
-> (DisplayRealFloat e -> Bool)
-> (DisplayRealFloat e -> Bool)
-> (DisplayRealFloat e -> Bool)
-> (DisplayRealFloat e -> Bool)
-> (DisplayRealFloat e -> DisplayRealFloat e -> DisplayRealFloat e)
-> RealFloat (DisplayRealFloat e)
Int -> DisplayRealFloat e -> DisplayRealFloat e
Integer -> Int -> DisplayRealFloat e
DisplayRealFloat e -> Bool
DisplayRealFloat e -> Int
DisplayRealFloat e -> Integer
DisplayRealFloat e -> (Int, Int)
DisplayRealFloat e -> (Integer, Int)
DisplayRealFloat e -> DisplayRealFloat e
DisplayRealFloat e -> DisplayRealFloat e -> DisplayRealFloat e
forall e. RealFloat e => Floating (DisplayRealFloat e)
forall e. RealFloat e => RealFrac (DisplayRealFloat e)
forall e.
RealFloat e =>
Int -> DisplayRealFloat e -> DisplayRealFloat e
forall e. RealFloat e => Integer -> Int -> DisplayRealFloat e
forall e. RealFloat e => DisplayRealFloat e -> Bool
forall e. RealFloat e => DisplayRealFloat e -> Int
forall e. RealFloat e => DisplayRealFloat e -> Integer
forall e. RealFloat e => DisplayRealFloat e -> (Int, Int)
forall e. RealFloat e => DisplayRealFloat e -> (Integer, Int)
forall e. RealFloat e => DisplayRealFloat e -> DisplayRealFloat e
forall e.
RealFloat e =>
DisplayRealFloat e -> DisplayRealFloat e -> DisplayRealFloat e
forall a.
RealFrac a
-> Floating a
-> (a -> Integer)
-> (a -> Int)
-> (a -> (Int, Int))
-> (a -> (Integer, Int))
-> (Integer -> Int -> a)
-> (a -> Int)
-> (a -> a)
-> (Int -> a -> a)
-> (a -> Bool)
-> (a -> Bool)
-> (a -> Bool)
-> (a -> Bool)
-> (a -> Bool)
-> (a -> a -> a)
-> RealFloat a
atan2 :: DisplayRealFloat e -> DisplayRealFloat e -> DisplayRealFloat e
$catan2 :: forall e.
RealFloat e =>
DisplayRealFloat e -> DisplayRealFloat e -> DisplayRealFloat e
isIEEE :: DisplayRealFloat e -> Bool
$cisIEEE :: forall e. RealFloat e => DisplayRealFloat e -> Bool
isNegativeZero :: DisplayRealFloat e -> Bool
$cisNegativeZero :: forall e. RealFloat e => DisplayRealFloat e -> Bool
isDenormalized :: DisplayRealFloat e -> Bool
$cisDenormalized :: forall e. RealFloat e => DisplayRealFloat e -> Bool
isInfinite :: DisplayRealFloat e -> Bool
$cisInfinite :: forall e. RealFloat e => DisplayRealFloat e -> Bool
isNaN :: DisplayRealFloat e -> Bool
$cisNaN :: forall e. RealFloat e => DisplayRealFloat e -> Bool
scaleFloat :: Int -> DisplayRealFloat e -> DisplayRealFloat e
$cscaleFloat :: forall e.
RealFloat e =>
Int -> DisplayRealFloat e -> DisplayRealFloat e
significand :: DisplayRealFloat e -> DisplayRealFloat e
$csignificand :: forall e. RealFloat e => DisplayRealFloat e -> DisplayRealFloat e
exponent :: DisplayRealFloat e -> Int
$cexponent :: forall e. RealFloat e => DisplayRealFloat e -> Int
encodeFloat :: Integer -> Int -> DisplayRealFloat e
$cencodeFloat :: forall e. RealFloat e => Integer -> Int -> DisplayRealFloat e
decodeFloat :: DisplayRealFloat e -> (Integer, Int)
$cdecodeFloat :: forall e. RealFloat e => DisplayRealFloat e -> (Integer, Int)
floatRange :: DisplayRealFloat e -> (Int, Int)
$cfloatRange :: forall e. RealFloat e => DisplayRealFloat e -> (Int, Int)
floatDigits :: DisplayRealFloat e -> Int
$cfloatDigits :: forall e. RealFloat e => DisplayRealFloat e -> Int
floatRadix :: DisplayRealFloat e -> Integer
$cfloatRadix :: forall e. RealFloat e => DisplayRealFloat e -> Integer
$cp2RealFloat :: forall e. RealFloat e => Floating (DisplayRealFloat e)
$cp1RealFloat :: forall e. RealFloat e => RealFrac (DisplayRealFloat e)
RealFloat, Fractional (DisplayRealFloat e)
Real (DisplayRealFloat e)
Real (DisplayRealFloat e)
-> Fractional (DisplayRealFloat e)
-> (forall b.
    Integral b =>
    DisplayRealFloat e -> (b, DisplayRealFloat e))
-> (forall b. Integral b => DisplayRealFloat e -> b)
-> (forall b. Integral b => DisplayRealFloat e -> b)
-> (forall b. Integral b => DisplayRealFloat e -> b)
-> (forall b. Integral b => DisplayRealFloat e -> b)
-> RealFrac (DisplayRealFloat e)
DisplayRealFloat e -> b
DisplayRealFloat e -> b
DisplayRealFloat e -> b
DisplayRealFloat e -> b
DisplayRealFloat e -> (b, DisplayRealFloat e)
forall b. Integral b => DisplayRealFloat e -> b
forall b.
Integral b =>
DisplayRealFloat e -> (b, DisplayRealFloat e)
forall a.
Real a
-> Fractional a
-> (forall b. Integral b => a -> (b, a))
-> (forall b. Integral b => a -> b)
-> (forall b. Integral b => a -> b)
-> (forall b. Integral b => a -> b)
-> (forall b. Integral b => a -> b)
-> RealFrac a
forall e. RealFrac e => Fractional (DisplayRealFloat e)
forall e. RealFrac e => Real (DisplayRealFloat e)
forall e b. (RealFrac e, Integral b) => DisplayRealFloat e -> b
forall e b.
(RealFrac e, Integral b) =>
DisplayRealFloat e -> (b, DisplayRealFloat e)
floor :: DisplayRealFloat e -> b
$cfloor :: forall e b. (RealFrac e, Integral b) => DisplayRealFloat e -> b
ceiling :: DisplayRealFloat e -> b
$cceiling :: forall e b. (RealFrac e, Integral b) => DisplayRealFloat e -> b
round :: DisplayRealFloat e -> b
$cround :: forall e b. (RealFrac e, Integral b) => DisplayRealFloat e -> b
truncate :: DisplayRealFloat e -> b
$ctruncate :: forall e b. (RealFrac e, Integral b) => DisplayRealFloat e -> b
properFraction :: DisplayRealFloat e -> (b, DisplayRealFloat e)
$cproperFraction :: forall e b.
(RealFrac e, Integral b) =>
DisplayRealFloat e -> (b, DisplayRealFloat e)
$cp2RealFrac :: forall e. RealFrac e => Fractional (DisplayRealFloat e)
$cp1RealFrac :: forall e. RealFrac e => Real (DisplayRealFloat e)
RealFrac, Num (DisplayRealFloat e)
Ord (DisplayRealFloat e)
Num (DisplayRealFloat e)
-> Ord (DisplayRealFloat e)
-> (DisplayRealFloat e -> Rational)
-> Real (DisplayRealFloat e)
DisplayRealFloat e -> Rational
forall a. Num a -> Ord a -> (a -> Rational) -> Real a
forall e. Real e => Num (DisplayRealFloat e)
forall e. Real e => Ord (DisplayRealFloat e)
forall e. Real e => DisplayRealFloat e -> Rational
toRational :: DisplayRealFloat e -> Rational
$ctoRational :: forall e. Real e => DisplayRealFloat e -> Rational
$cp2Real :: forall e. Real e => Ord (DisplayRealFloat e)
$cp1Real :: forall e. Real e => Num (DisplayRealFloat e)
Real, Eq (DisplayRealFloat e)
Eq (DisplayRealFloat e)
-> (DisplayRealFloat e -> DisplayRealFloat e -> Ordering)
-> (DisplayRealFloat e -> DisplayRealFloat e -> Bool)
-> (DisplayRealFloat e -> DisplayRealFloat e -> Bool)
-> (DisplayRealFloat e -> DisplayRealFloat e -> Bool)
-> (DisplayRealFloat e -> DisplayRealFloat e -> Bool)
-> (DisplayRealFloat e -> DisplayRealFloat e -> DisplayRealFloat e)
-> (DisplayRealFloat e -> DisplayRealFloat e -> DisplayRealFloat e)
-> Ord (DisplayRealFloat e)
DisplayRealFloat e -> DisplayRealFloat e -> Bool
DisplayRealFloat e -> DisplayRealFloat e -> Ordering
DisplayRealFloat e -> DisplayRealFloat e -> DisplayRealFloat e
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
forall e. Ord e => Eq (DisplayRealFloat e)
forall e. Ord e => DisplayRealFloat e -> DisplayRealFloat e -> Bool
forall e.
Ord e =>
DisplayRealFloat e -> DisplayRealFloat e -> Ordering
forall e.
Ord e =>
DisplayRealFloat e -> DisplayRealFloat e -> DisplayRealFloat e
min :: DisplayRealFloat e -> DisplayRealFloat e -> DisplayRealFloat e
$cmin :: forall e.
Ord e =>
DisplayRealFloat e -> DisplayRealFloat e -> DisplayRealFloat e
max :: DisplayRealFloat e -> DisplayRealFloat e -> DisplayRealFloat e
$cmax :: forall e.
Ord e =>
DisplayRealFloat e -> DisplayRealFloat e -> DisplayRealFloat e
>= :: DisplayRealFloat e -> DisplayRealFloat e -> Bool
$c>= :: forall e. Ord e => DisplayRealFloat e -> DisplayRealFloat e -> Bool
> :: DisplayRealFloat e -> DisplayRealFloat e -> Bool
$c> :: forall e. Ord e => DisplayRealFloat e -> DisplayRealFloat e -> Bool
<= :: DisplayRealFloat e -> DisplayRealFloat e -> Bool
$c<= :: forall e. Ord e => DisplayRealFloat e -> DisplayRealFloat e -> Bool
< :: DisplayRealFloat e -> DisplayRealFloat e -> Bool
$c< :: forall e. Ord e => DisplayRealFloat e -> DisplayRealFloat e -> Bool
compare :: DisplayRealFloat e -> DisplayRealFloat e -> Ordering
$ccompare :: forall e.
Ord e =>
DisplayRealFloat e -> DisplayRealFloat e -> Ordering
$cp1Ord :: forall e. Ord e => Eq (DisplayRealFloat e)
Ord, DisplayRealFloat e -> DisplayRealFloat e -> Bool
(DisplayRealFloat e -> DisplayRealFloat e -> Bool)
-> (DisplayRealFloat e -> DisplayRealFloat e -> Bool)
-> Eq (DisplayRealFloat e)
forall e. Eq e => DisplayRealFloat e -> DisplayRealFloat e -> Bool
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: DisplayRealFloat e -> DisplayRealFloat e -> Bool
$c/= :: forall e. Eq e => DisplayRealFloat e -> DisplayRealFloat e -> Bool
== :: DisplayRealFloat e -> DisplayRealFloat e -> Bool
$c== :: forall e. Eq e => DisplayRealFloat e -> DisplayRealFloat e -> Bool
Eq, Integer -> DisplayRealFloat e
DisplayRealFloat e -> DisplayRealFloat e
DisplayRealFloat e -> DisplayRealFloat e -> DisplayRealFloat e
(DisplayRealFloat e -> DisplayRealFloat e -> DisplayRealFloat e)
-> (DisplayRealFloat e -> DisplayRealFloat e -> DisplayRealFloat e)
-> (DisplayRealFloat e -> DisplayRealFloat e -> DisplayRealFloat e)
-> (DisplayRealFloat e -> DisplayRealFloat e)
-> (DisplayRealFloat e -> DisplayRealFloat e)
-> (DisplayRealFloat e -> DisplayRealFloat e)
-> (Integer -> DisplayRealFloat e)
-> Num (DisplayRealFloat e)
forall e. Num e => Integer -> DisplayRealFloat e
forall e. Num e => DisplayRealFloat e -> DisplayRealFloat e
forall e.
Num e =>
DisplayRealFloat e -> DisplayRealFloat e -> DisplayRealFloat e
forall a.
(a -> a -> a)
-> (a -> a -> a)
-> (a -> a -> a)
-> (a -> a)
-> (a -> a)
-> (a -> a)
-> (Integer -> a)
-> Num a
fromInteger :: Integer -> DisplayRealFloat e
$cfromInteger :: forall e. Num e => Integer -> DisplayRealFloat e
signum :: DisplayRealFloat e -> DisplayRealFloat e
$csignum :: forall e. Num e => DisplayRealFloat e -> DisplayRealFloat e
abs :: DisplayRealFloat e -> DisplayRealFloat e
$cabs :: forall e. Num e => DisplayRealFloat e -> DisplayRealFloat e
negate :: DisplayRealFloat e -> DisplayRealFloat e
$cnegate :: forall e. Num e => DisplayRealFloat e -> DisplayRealFloat e
* :: DisplayRealFloat e -> DisplayRealFloat e -> DisplayRealFloat e
$c* :: forall e.
Num e =>
DisplayRealFloat e -> DisplayRealFloat e -> DisplayRealFloat e
- :: DisplayRealFloat e -> DisplayRealFloat e -> DisplayRealFloat e
$c- :: forall e.
Num e =>
DisplayRealFloat e -> DisplayRealFloat e -> DisplayRealFloat e
+ :: DisplayRealFloat e -> DisplayRealFloat e -> DisplayRealFloat e
$c+ :: forall e.
Num e =>
DisplayRealFloat e -> DisplayRealFloat e -> DisplayRealFloat e
Num, Num (DisplayRealFloat e)
Num (DisplayRealFloat e)
-> (DisplayRealFloat e -> DisplayRealFloat e -> DisplayRealFloat e)
-> (DisplayRealFloat e -> DisplayRealFloat e)
-> (Rational -> DisplayRealFloat e)
-> Fractional (DisplayRealFloat e)
Rational -> DisplayRealFloat e
DisplayRealFloat e -> DisplayRealFloat e
DisplayRealFloat e -> DisplayRealFloat e -> DisplayRealFloat e
forall e. Fractional e => Num (DisplayRealFloat e)
forall e. Fractional e => Rational -> DisplayRealFloat e
forall e. Fractional e => DisplayRealFloat e -> DisplayRealFloat e
forall e.
Fractional e =>
DisplayRealFloat e -> DisplayRealFloat e -> DisplayRealFloat e
forall a.
Num a
-> (a -> a -> a) -> (a -> a) -> (Rational -> a) -> Fractional a
fromRational :: Rational -> DisplayRealFloat e
$cfromRational :: forall e. Fractional e => Rational -> DisplayRealFloat e
recip :: DisplayRealFloat e -> DisplayRealFloat e
$crecip :: forall e. Fractional e => DisplayRealFloat e -> DisplayRealFloat e
/ :: DisplayRealFloat e -> DisplayRealFloat e -> DisplayRealFloat e
$c/ :: forall e.
Fractional e =>
DisplayRealFloat e -> DisplayRealFloat e -> DisplayRealFloat e
$cp1Fractional :: forall e. Fractional e => Num (DisplayRealFloat e)
Fractional, Fractional (DisplayRealFloat e)
DisplayRealFloat e
Fractional (DisplayRealFloat e)
-> DisplayRealFloat e
-> (DisplayRealFloat e -> DisplayRealFloat e)
-> (DisplayRealFloat e -> DisplayRealFloat e)
-> (DisplayRealFloat e -> DisplayRealFloat e)
-> (DisplayRealFloat e -> DisplayRealFloat e -> DisplayRealFloat e)
-> (DisplayRealFloat e -> DisplayRealFloat e -> DisplayRealFloat e)
-> (DisplayRealFloat e -> DisplayRealFloat e)
-> (DisplayRealFloat e -> DisplayRealFloat e)
-> (DisplayRealFloat e -> DisplayRealFloat e)
-> (DisplayRealFloat e -> DisplayRealFloat e)
-> (DisplayRealFloat e -> DisplayRealFloat e)
-> (DisplayRealFloat e -> DisplayRealFloat e)
-> (DisplayRealFloat e -> DisplayRealFloat e)
-> (DisplayRealFloat e -> DisplayRealFloat e)
-> (DisplayRealFloat e -> DisplayRealFloat e)
-> (DisplayRealFloat e -> DisplayRealFloat e)
-> (DisplayRealFloat e -> DisplayRealFloat e)
-> (DisplayRealFloat e -> DisplayRealFloat e)
-> (DisplayRealFloat e -> DisplayRealFloat e)
-> (DisplayRealFloat e -> DisplayRealFloat e)
-> (DisplayRealFloat e -> DisplayRealFloat e)
-> (DisplayRealFloat e -> DisplayRealFloat e)
-> Floating (DisplayRealFloat e)
DisplayRealFloat e -> DisplayRealFloat e
DisplayRealFloat e -> DisplayRealFloat e -> DisplayRealFloat e
forall e. Floating e => Fractional (DisplayRealFloat e)
forall e. Floating e => DisplayRealFloat e
forall e. Floating e => DisplayRealFloat e -> DisplayRealFloat e
forall e.
Floating e =>
DisplayRealFloat e -> DisplayRealFloat e -> DisplayRealFloat e
forall a.
Fractional a
-> a
-> (a -> a)
-> (a -> a)
-> (a -> a)
-> (a -> a -> a)
-> (a -> a -> a)
-> (a -> a)
-> (a -> a)
-> (a -> a)
-> (a -> a)
-> (a -> a)
-> (a -> a)
-> (a -> a)
-> (a -> a)
-> (a -> a)
-> (a -> a)
-> (a -> a)
-> (a -> a)
-> (a -> a)
-> (a -> a)
-> (a -> a)
-> (a -> a)
-> Floating a
log1mexp :: DisplayRealFloat e -> DisplayRealFloat e
$clog1mexp :: forall e. Floating e => DisplayRealFloat e -> DisplayRealFloat e
log1pexp :: DisplayRealFloat e -> DisplayRealFloat e
$clog1pexp :: forall e. Floating e => DisplayRealFloat e -> DisplayRealFloat e
expm1 :: DisplayRealFloat e -> DisplayRealFloat e
$cexpm1 :: forall e. Floating e => DisplayRealFloat e -> DisplayRealFloat e
log1p :: DisplayRealFloat e -> DisplayRealFloat e
$clog1p :: forall e. Floating e => DisplayRealFloat e -> DisplayRealFloat e
atanh :: DisplayRealFloat e -> DisplayRealFloat e
$catanh :: forall e. Floating e => DisplayRealFloat e -> DisplayRealFloat e
acosh :: DisplayRealFloat e -> DisplayRealFloat e
$cacosh :: forall e. Floating e => DisplayRealFloat e -> DisplayRealFloat e
asinh :: DisplayRealFloat e -> DisplayRealFloat e
$casinh :: forall e. Floating e => DisplayRealFloat e -> DisplayRealFloat e
tanh :: DisplayRealFloat e -> DisplayRealFloat e
$ctanh :: forall e. Floating e => DisplayRealFloat e -> DisplayRealFloat e
cosh :: DisplayRealFloat e -> DisplayRealFloat e
$ccosh :: forall e. Floating e => DisplayRealFloat e -> DisplayRealFloat e
sinh :: DisplayRealFloat e -> DisplayRealFloat e
$csinh :: forall e. Floating e => DisplayRealFloat e -> DisplayRealFloat e
atan :: DisplayRealFloat e -> DisplayRealFloat e
$catan :: forall e. Floating e => DisplayRealFloat e -> DisplayRealFloat e
acos :: DisplayRealFloat e -> DisplayRealFloat e
$cacos :: forall e. Floating e => DisplayRealFloat e -> DisplayRealFloat e
asin :: DisplayRealFloat e -> DisplayRealFloat e
$casin :: forall e. Floating e => DisplayRealFloat e -> DisplayRealFloat e
tan :: DisplayRealFloat e -> DisplayRealFloat e
$ctan :: forall e. Floating e => DisplayRealFloat e -> DisplayRealFloat e
cos :: DisplayRealFloat e -> DisplayRealFloat e
$ccos :: forall e. Floating e => DisplayRealFloat e -> DisplayRealFloat e
sin :: DisplayRealFloat e -> DisplayRealFloat e
$csin :: forall e. Floating e => DisplayRealFloat e -> DisplayRealFloat e
logBase :: DisplayRealFloat e -> DisplayRealFloat e -> DisplayRealFloat e
$clogBase :: forall e.
Floating e =>
DisplayRealFloat e -> DisplayRealFloat e -> DisplayRealFloat e
** :: DisplayRealFloat e -> DisplayRealFloat e -> DisplayRealFloat e
$c** :: forall e.
Floating e =>
DisplayRealFloat e -> DisplayRealFloat e -> DisplayRealFloat e
sqrt :: DisplayRealFloat e -> DisplayRealFloat e
$csqrt :: forall e. Floating e => DisplayRealFloat e -> DisplayRealFloat e
log :: DisplayRealFloat e -> DisplayRealFloat e
$clog :: forall e. Floating e => DisplayRealFloat e -> DisplayRealFloat e
exp :: DisplayRealFloat e -> DisplayRealFloat e
$cexp :: forall e. Floating e => DisplayRealFloat e -> DisplayRealFloat e
pi :: DisplayRealFloat e
$cpi :: forall e. Floating e => DisplayRealFloat e
$cp1Floating :: forall e. Floating e => Fractional (DisplayRealFloat e)
Floating)

-- @since 0.0.1.0
instance RealFloat e => Display (DisplayRealFloat e) where
  displayBuilder :: DisplayRealFloat e -> Builder
displayBuilder = DisplayRealFloat e -> Builder
forall a. RealFloat a => a -> Builder
TB.realFloat

-- | @since 0.0.1.0
deriving via (ShowInstance ()) instance Display ()

-- | @since 0.0.1.0
deriving via (ShowInstance Bool) instance Display Bool

-- | @since 0.0.1.0
instance Display Char where
  displayBuilder :: Char -> Builder
displayBuilder Char
'\'' = Builder
"'\\''"
  displayBuilder Char
c = Builder
"'" Builder -> Builder -> Builder
forall a. Semigroup a => a -> a -> a
<> Char -> Builder
TB.singleton Char
c Builder -> Builder -> Builder
forall a. Semigroup a => a -> a -> a
<> Builder
"\'"
  -- 'displayList' is overloaded, so that when the @Display [a]@ instance calls 'displayList',
  -- we end up with a nice string enclosed between double quotes.
  displayList :: String -> Builder
displayList String
cs = String -> Builder
TB.fromString (String -> Builder) -> String -> Builder
forall a b. (a -> b) -> a -> b
$ String
"\"" String -> ShowS
forall a. Semigroup a => a -> a -> a
<> String -> ShowS
showLitString String
cs String
"\""

-- | Lazy 'TL.Text'
--
-- @since 0.0.1.0
instance Display TL.Text where
  displayBuilder :: Text -> Builder
displayBuilder = Text -> Builder
TB.fromLazyText

-- | Strict 'Data.Text.Text'
--
-- @since 0.0.1.0
instance Display Text where
  displayBuilder :: Text -> Builder
displayBuilder = Text -> Builder
TB.fromText

-- | @since 0.0.1.0
instance Display a => Display [a] where
  {-# SPECIALISE instance Display [String] #-}
  {-# SPECIALISE instance Display [Char] #-}
  {-# SPECIALISE instance Display [Int] #-}
  -- In this instance, 'displayBuilder' is defined in terms of 'displayList', which for most types
  -- is defined as the default written in the class declaration.
  -- But when @a ~ Char@, there is an explicit implementation that is selected instead, which
  -- provides the rendering of the character string between double quotes.
  displayBuilder :: [a] -> Builder
displayBuilder = [a] -> Builder
forall a. Display a => [a] -> Builder
displayList

-- | @since 0.0.1.0
instance Display a => Display (NonEmpty a) where
  displayBuilder :: NonEmpty a -> Builder
displayBuilder (a
a :| [a]
as) = a -> Builder
forall a. Display a => a -> Builder
displayBuilder a
a Builder -> Builder -> Builder
forall a. Semigroup a => a -> a -> a
<> String -> Builder
TB.fromString String
" :| " Builder -> Builder -> Builder
forall a. Semigroup a => a -> a -> a
<> [a] -> Builder
forall a. Display a => a -> Builder
displayBuilder [a]
as

-- | @since 0.0.1.0
instance Display a => Display (Maybe a) where
  -- In this instance, we define 'displayPrec' rather than 'displayBuilder' as we need to decide
  -- whether or not to surround ourselves in parentheses based on the surrounding context.
  -- If the precedence parameter is higher than 10 (the precedence of constructor application)
  -- then we indeed need to surround ourselves in parentheses to avoid malformed outputs
  -- such as @Just Just 5@.
  -- We then set the precedence parameter of the inner 'displayPrec' to 11, as even
  -- constructor application is not strong enough to avoid parentheses.
  displayPrec :: Int -> Maybe a -> Builder
displayPrec Int
_ Maybe a
Nothing = Builder
"Nothing"
  displayPrec Int
prec (Just a
a) = Bool -> Builder -> Builder
displayParen (Int
prec Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
> Int
10) (Builder -> Builder) -> Builder -> Builder
forall a b. (a -> b) -> a -> b
$ Builder
"Just " Builder -> Builder -> Builder
forall a. Semigroup a => a -> a -> a
<> Int -> a -> Builder
forall a. Display a => Int -> a -> Builder
displayPrec Int
11 a
a

-- | @since 0.0.1.0
deriving via (DisplayRealFloat Double) instance Display Double

-- | @since 0.0.1.0
deriving via (DisplayRealFloat Float) instance Display Float

-- | @since 0.0.1.0
deriving via (DisplayDecimal Int) instance Display Int

-- | @since 0.0.1.0
deriving via (DisplayDecimal Int8) instance Display Int8

-- | @since 0.0.1.0
deriving via (DisplayDecimal Int16) instance Display Int16

-- | @since 0.0.1.0
deriving via (DisplayDecimal Int32) instance Display Int32

-- | @since 0.0.1.0
deriving via (DisplayDecimal Int64) instance Display Int64

-- | @since 0.0.1.0
deriving via (DisplayDecimal Integer) instance Display Integer

-- | @since 0.0.1.0
deriving via (DisplayDecimal Word) instance Display Word

-- | @since 0.0.1.0
deriving via (DisplayDecimal Word8) instance Display Word8

-- | @since 0.0.1.0
deriving via (DisplayDecimal Word16) instance Display Word16

-- | @since 0.0.1.0
deriving via (DisplayDecimal Word32) instance Display Word32

-- | @since 0.0.1.0
deriving via (DisplayDecimal Word64) instance Display Word64

-- | @since 0.0.1.0
deriving via (ShowInstance IOException) instance Display IOException

-- | @since 0.0.1.0
deriving via (ShowInstance SomeException) instance Display SomeException

-- | @since 0.0.1.0
instance (Display a, Display b) => Display (a, b) where
  displayBuilder :: (a, b) -> Builder
displayBuilder (a
a, b
b) = Builder
"(" Builder -> Builder -> Builder
forall a. Semigroup a => a -> a -> a
<> a -> Builder
forall a. Display a => a -> Builder
displayBuilder a
a Builder -> Builder -> Builder
forall a. Semigroup a => a -> a -> a
<>  Builder
"," Builder -> Builder -> Builder
forall a. Semigroup a => a -> a -> a
<> b -> Builder
forall a. Display a => a -> Builder
displayBuilder b
b Builder -> Builder -> Builder
forall a. Semigroup a => a -> a -> a
<> Builder
")"

-- | @since 0.0.1.0
instance (Display a, Display b, Display c) => Display (a, b, c) where
  displayBuilder :: (a, b, c) -> Builder
displayBuilder (a
a, b
b, c
c) = Builder
"(" Builder -> Builder -> Builder
forall a. Semigroup a => a -> a -> a
<> a -> Builder
forall a. Display a => a -> Builder
displayBuilder a
a Builder -> Builder -> Builder
forall a. Semigroup a => a -> a -> a
<>  Builder
"," Builder -> Builder -> Builder
forall a. Semigroup a => a -> a -> a
<> b -> Builder
forall a. Display a => a -> Builder
displayBuilder b
b Builder -> Builder -> Builder
forall a. Semigroup a => a -> a -> a
<> Builder
"," Builder -> Builder -> Builder
forall a. Semigroup a => a -> a -> a
<> c -> Builder
forall a. Display a => a -> Builder
displayBuilder c
c Builder -> Builder -> Builder
forall a. Semigroup a => a -> a -> a
<> Builder
")"

-- | @since 0.0.1.0
instance (Display a, Display b, Display c, Display d) => Display (a, b, c, d) where
  displayBuilder :: (a, b, c, d) -> Builder
displayBuilder (a
a, b
b, c
c, d
d) = Builder
"(" Builder -> Builder -> Builder
forall a. Semigroup a => a -> a -> a
<> a -> Builder
forall a. Display a => a -> Builder
displayBuilder a
a Builder -> Builder -> Builder
forall a. Semigroup a => a -> a -> a
<>  Builder
"," Builder -> Builder -> Builder
forall a. Semigroup a => a -> a -> a
<> b -> Builder
forall a. Display a => a -> Builder
displayBuilder b
b Builder -> Builder -> Builder
forall a. Semigroup a => a -> a -> a
<> Builder
"," Builder -> Builder -> Builder
forall a. Semigroup a => a -> a -> a
<> c -> Builder
forall a. Display a => a -> Builder
displayBuilder c
c Builder -> Builder -> Builder
forall a. Semigroup a => a -> a -> a
<> Builder
"," Builder -> Builder -> Builder
forall a. Semigroup a => a -> a -> a
<> d -> Builder
forall a. Display a => a -> Builder
displayBuilder d
d Builder -> Builder -> Builder
forall a. Semigroup a => a -> a -> a
<> Builder
")"

-- $designChoices
--
-- === A “Lawless Typeclass”
--
-- The 'Display' typeclass does not contain any law. This is a controversial choice for some people,
-- but the truth is that there are not any laws to ask of the consumer that are not already enforced
-- by the type system and the internals of the 'Data.Text.Internal.Text' type.
--
-- === "🚫 You should not try to display functions!"
--
-- Sometimes, when using the library, you may encounter this message:
--
-- > • 🚫 You should not try to display functions!
-- >   💡 Write a 'newtype' wrapper that represents your domain more accurately.
-- >      If you are not consciously trying to use `display` on a function,
-- >      make sure that you are not missing an argument somewhere.
--
-- The 'display' library does not allow the definition and usage of 'Display' on
-- bare function types (@(a -> b)@).
-- Experience and time have shown that due to partial application being baked in the language,
-- many users encounter a partial application-related error message when a simple missing
-- argument to a function is the root cause.
--
-- There may be legitimate uses of a 'Display' instance on a function type.
-- But these usages are extremely dependent on their domain of application.
-- That is why it is best to wrap them in a newtype that can better
-- express and enforce the domain.
--
-- === "🚫 You should not try to display ByteStrings!"
--
-- An arbitrary ByteStrings cannot be safely converted to text without prior knowledge of its encoding.
--
-- As such, in order to avoid dangerously blind conversions, it is recommended to use a specialised
-- function such as 'Data.Text.Encoding.decodeUtf8'' or 'Data.Text.Encoding.decodeUtf8With' if you wish to turn a UTF8-encoded ByteString
-- to Text.