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

-- |
--  Module      : Data.Text.Display
--  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 qualified Data.ByteString.Lazy as BL
import Data.Int
import Data.Kind
import Data.List.NonEmpty
import Data.Proxy
import Data.Text (Text)
import qualified Data.Text as T
import qualified Data.Text.Lazy as TL
import Data.Text.Lazy.Builder (Builder)
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 Data.Void (Void)
import Data.Word
import GHC.TypeLits

-- | 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
  --
  -- > import qualified Data.Text.Lazy.Builder as TB
  -- >
  -- > instance Display Char where
  -- >   displayBuilder c = TB.fromText $ T.singleton c
  -- >   displayList cs = TB.fromText $ T.pack 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) = Builder
"[" Builder -> Builder -> Builder
forall a. Semigroup a => a -> a -> a
<> a -> Builder
forall a. Display a => a -> Builder
displayBuilder a
x Builder -> Builder -> Builder
forall a. Semigroup a => a -> a -> a
<> (a -> Builder) -> [a] -> Builder
forall m a. Monoid m => (a -> m) -> [a] -> m
forall (t :: * -> *) m a.
(Foldable t, Monoid m) =>
(a -> m) -> t a -> m
foldMap a -> Builder
go [a]
xs Builder -> Builder -> Builder
forall a. Semigroup a => a -> a -> a
<> Builder
"]"
    where
      go :: a -> Builder
      go :: a -> Builder
go a
y = 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 :: forall a. Display a => 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 (forall {k} (t :: k). Proxy t
forall (t :: Symbol). 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
    ( Int -> ShowInstance a -> ShowS
[ShowInstance a] -> ShowS
ShowInstance a -> String
(Int -> ShowInstance a -> ShowS)
-> (ShowInstance a -> String)
-> ([ShowInstance a] -> ShowS)
-> Show (ShowInstance a)
forall a. Show a => Int -> ShowInstance a -> ShowS
forall a. Show a => [ShowInstance a] -> ShowS
forall a. Show a => ShowInstance a -> String
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: forall a. Show a => Int -> ShowInstance a -> ShowS
showsPrec :: Int -> ShowInstance a -> ShowS
$cshow :: forall a. Show a => ShowInstance a -> String
show :: ShowInstance a -> String
$cshowList :: forall a. Show a => [ShowInstance a] -> ShowS
showList :: [ShowInstance a] -> ShowS
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
$cquot :: forall e.
Integral e =>
DisplayDecimal e -> DisplayDecimal e -> DisplayDecimal e
quot :: DisplayDecimal e -> DisplayDecimal e -> DisplayDecimal e
$crem :: forall e.
Integral e =>
DisplayDecimal e -> DisplayDecimal e -> DisplayDecimal e
rem :: DisplayDecimal e -> DisplayDecimal e -> DisplayDecimal e
$cdiv :: forall e.
Integral e =>
DisplayDecimal e -> DisplayDecimal e -> DisplayDecimal e
div :: DisplayDecimal e -> DisplayDecimal e -> DisplayDecimal e
$cmod :: forall e.
Integral e =>
DisplayDecimal e -> DisplayDecimal e -> DisplayDecimal e
mod :: DisplayDecimal e -> DisplayDecimal e -> DisplayDecimal e
$cquotRem :: forall e.
Integral e =>
DisplayDecimal e
-> DisplayDecimal e -> (DisplayDecimal e, DisplayDecimal e)
quotRem :: DisplayDecimal e
-> DisplayDecimal e -> (DisplayDecimal e, DisplayDecimal e)
$cdivMod :: forall e.
Integral e =>
DisplayDecimal e
-> DisplayDecimal e -> (DisplayDecimal e, DisplayDecimal e)
divMod :: DisplayDecimal e
-> DisplayDecimal e -> (DisplayDecimal e, DisplayDecimal e)
$ctoInteger :: forall e. Integral e => DisplayDecimal e -> Integer
toInteger :: DisplayDecimal e -> Integer
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
$ctoRational :: forall e. Real e => DisplayDecimal e -> Rational
toRational :: DisplayDecimal e -> Rational
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
$csucc :: forall e. Enum e => DisplayDecimal e -> DisplayDecimal e
succ :: DisplayDecimal e -> DisplayDecimal e
$cpred :: forall e. Enum e => DisplayDecimal e -> DisplayDecimal e
pred :: DisplayDecimal e -> DisplayDecimal e
$ctoEnum :: forall e. Enum e => Int -> DisplayDecimal e
toEnum :: Int -> DisplayDecimal e
$cfromEnum :: forall e. Enum e => DisplayDecimal e -> Int
fromEnum :: DisplayDecimal e -> Int
$cenumFrom :: forall e. Enum e => DisplayDecimal e -> [DisplayDecimal e]
enumFrom :: DisplayDecimal e -> [DisplayDecimal e]
$cenumFromThen :: forall e.
Enum e =>
DisplayDecimal e -> DisplayDecimal e -> [DisplayDecimal e]
enumFromThen :: DisplayDecimal e -> DisplayDecimal e -> [DisplayDecimal e]
$cenumFromTo :: forall e.
Enum e =>
DisplayDecimal e -> DisplayDecimal e -> [DisplayDecimal e]
enumFromTo :: DisplayDecimal e -> DisplayDecimal e -> [DisplayDecimal e]
$cenumFromThenTo :: forall e.
Enum e =>
DisplayDecimal e
-> DisplayDecimal e -> DisplayDecimal e -> [DisplayDecimal e]
enumFromThenTo :: DisplayDecimal e
-> DisplayDecimal 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
$ccompare :: forall e. Ord e => DisplayDecimal e -> DisplayDecimal e -> Ordering
compare :: DisplayDecimal e -> DisplayDecimal e -> Ordering
$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
>= :: DisplayDecimal e -> DisplayDecimal e -> Bool
$cmax :: forall e.
Ord e =>
DisplayDecimal e -> DisplayDecimal e -> DisplayDecimal e
max :: DisplayDecimal e -> DisplayDecimal e -> DisplayDecimal e
$cmin :: forall e.
Ord e =>
DisplayDecimal e -> DisplayDecimal e -> DisplayDecimal e
min :: DisplayDecimal e -> DisplayDecimal e -> 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
$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
* :: DisplayDecimal e -> DisplayDecimal e -> DisplayDecimal e
$cnegate :: forall e. Num e => DisplayDecimal e -> DisplayDecimal e
negate :: DisplayDecimal e -> DisplayDecimal e
$cabs :: forall e. Num e => DisplayDecimal e -> DisplayDecimal e
abs :: DisplayDecimal e -> DisplayDecimal e
$csignum :: forall e. Num e => DisplayDecimal e -> DisplayDecimal e
signum :: DisplayDecimal e -> DisplayDecimal e
$cfromInteger :: forall e. Num e => Integer -> DisplayDecimal e
fromInteger :: Integer -> 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
$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
/= :: 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
$cfloatRadix :: forall e. RealFloat e => DisplayRealFloat e -> Integer
floatRadix :: DisplayRealFloat e -> Integer
$cfloatDigits :: forall e. RealFloat e => DisplayRealFloat e -> Int
floatDigits :: DisplayRealFloat e -> Int
$cfloatRange :: forall e. RealFloat e => DisplayRealFloat e -> (Int, Int)
floatRange :: DisplayRealFloat e -> (Int, Int)
$cdecodeFloat :: forall e. RealFloat e => DisplayRealFloat e -> (Integer, Int)
decodeFloat :: DisplayRealFloat e -> (Integer, Int)
$cencodeFloat :: forall e. RealFloat e => Integer -> Int -> DisplayRealFloat e
encodeFloat :: Integer -> Int -> DisplayRealFloat e
$cexponent :: forall e. RealFloat e => DisplayRealFloat e -> Int
exponent :: DisplayRealFloat e -> Int
$csignificand :: forall e. RealFloat e => DisplayRealFloat e -> DisplayRealFloat e
significand :: DisplayRealFloat e -> DisplayRealFloat e
$cscaleFloat :: forall e.
RealFloat e =>
Int -> DisplayRealFloat e -> DisplayRealFloat e
scaleFloat :: Int -> DisplayRealFloat e -> DisplayRealFloat e
$cisNaN :: forall e. RealFloat e => DisplayRealFloat e -> Bool
isNaN :: DisplayRealFloat e -> Bool
$cisInfinite :: forall e. RealFloat e => DisplayRealFloat e -> Bool
isInfinite :: DisplayRealFloat e -> Bool
$cisDenormalized :: forall e. RealFloat e => DisplayRealFloat e -> Bool
isDenormalized :: DisplayRealFloat e -> Bool
$cisNegativeZero :: forall e. RealFloat e => DisplayRealFloat e -> Bool
isNegativeZero :: DisplayRealFloat e -> Bool
$cisIEEE :: forall e. RealFloat e => DisplayRealFloat e -> Bool
isIEEE :: DisplayRealFloat e -> Bool
$catan2 :: forall e.
RealFloat e =>
DisplayRealFloat e -> DisplayRealFloat e -> DisplayRealFloat e
atan2 :: DisplayRealFloat e -> DisplayRealFloat e -> 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)
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)
$cproperFraction :: forall e b.
(RealFrac e, Integral b) =>
DisplayRealFloat e -> (b, DisplayRealFloat e)
properFraction :: forall b.
Integral b =>
DisplayRealFloat e -> (b, DisplayRealFloat e)
$ctruncate :: forall e b. (RealFrac e, Integral b) => DisplayRealFloat e -> b
truncate :: forall b. Integral b => DisplayRealFloat e -> b
$cround :: forall e b. (RealFrac e, Integral b) => DisplayRealFloat e -> b
round :: forall b. Integral b => DisplayRealFloat e -> b
$cceiling :: forall e b. (RealFrac e, Integral b) => DisplayRealFloat e -> b
ceiling :: forall b. Integral b => DisplayRealFloat e -> b
$cfloor :: forall e b. (RealFrac e, Integral b) => DisplayRealFloat e -> b
floor :: forall b. Integral b => DisplayRealFloat e -> b
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
$ctoRational :: forall e. Real e => DisplayRealFloat e -> Rational
toRational :: DisplayRealFloat e -> Rational
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
$ccompare :: forall e.
Ord e =>
DisplayRealFloat e -> DisplayRealFloat e -> Ordering
compare :: DisplayRealFloat e -> DisplayRealFloat e -> Ordering
$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
>= :: DisplayRealFloat e -> DisplayRealFloat e -> Bool
$cmax :: forall e.
Ord e =>
DisplayRealFloat e -> DisplayRealFloat e -> DisplayRealFloat e
max :: DisplayRealFloat e -> DisplayRealFloat e -> DisplayRealFloat e
$cmin :: forall e.
Ord e =>
DisplayRealFloat e -> DisplayRealFloat e -> DisplayRealFloat e
min :: DisplayRealFloat e -> DisplayRealFloat e -> 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
$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
/= :: 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
$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
* :: DisplayRealFloat e -> DisplayRealFloat e -> DisplayRealFloat e
$cnegate :: forall e. Num e => DisplayRealFloat e -> DisplayRealFloat e
negate :: DisplayRealFloat e -> DisplayRealFloat e
$cabs :: forall e. Num e => DisplayRealFloat e -> DisplayRealFloat e
abs :: DisplayRealFloat e -> DisplayRealFloat e
$csignum :: forall e. Num e => DisplayRealFloat e -> DisplayRealFloat e
signum :: DisplayRealFloat e -> DisplayRealFloat e
$cfromInteger :: forall e. Num e => Integer -> DisplayRealFloat e
fromInteger :: Integer -> 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
$c/ :: forall e.
Fractional e =>
DisplayRealFloat e -> DisplayRealFloat e -> DisplayRealFloat e
/ :: DisplayRealFloat e -> DisplayRealFloat e -> DisplayRealFloat e
$crecip :: forall e. Fractional e => DisplayRealFloat e -> DisplayRealFloat e
recip :: DisplayRealFloat e -> DisplayRealFloat e
$cfromRational :: forall e. Fractional e => Rational -> DisplayRealFloat e
fromRational :: Rational -> 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
$cpi :: forall e. Floating e => DisplayRealFloat e
pi :: DisplayRealFloat e
$cexp :: forall e. Floating e => DisplayRealFloat e -> DisplayRealFloat e
exp :: DisplayRealFloat e -> DisplayRealFloat e
$clog :: forall e. Floating e => DisplayRealFloat e -> DisplayRealFloat e
log :: DisplayRealFloat e -> DisplayRealFloat e
$csqrt :: forall e. Floating e => DisplayRealFloat e -> DisplayRealFloat e
sqrt :: DisplayRealFloat e -> DisplayRealFloat e
$c** :: forall e.
Floating e =>
DisplayRealFloat e -> DisplayRealFloat e -> DisplayRealFloat e
** :: DisplayRealFloat e -> DisplayRealFloat e -> DisplayRealFloat e
$clogBase :: forall e.
Floating e =>
DisplayRealFloat e -> DisplayRealFloat e -> DisplayRealFloat e
logBase :: DisplayRealFloat e -> DisplayRealFloat e -> DisplayRealFloat e
$csin :: forall e. Floating e => DisplayRealFloat e -> DisplayRealFloat e
sin :: DisplayRealFloat e -> DisplayRealFloat e
$ccos :: forall e. Floating e => DisplayRealFloat e -> DisplayRealFloat e
cos :: DisplayRealFloat e -> DisplayRealFloat e
$ctan :: forall e. Floating e => DisplayRealFloat e -> DisplayRealFloat e
tan :: DisplayRealFloat e -> DisplayRealFloat e
$casin :: forall e. Floating e => DisplayRealFloat e -> DisplayRealFloat e
asin :: DisplayRealFloat e -> DisplayRealFloat e
$cacos :: forall e. Floating e => DisplayRealFloat e -> DisplayRealFloat e
acos :: DisplayRealFloat e -> DisplayRealFloat e
$catan :: forall e. Floating e => DisplayRealFloat e -> DisplayRealFloat e
atan :: DisplayRealFloat e -> DisplayRealFloat e
$csinh :: forall e. Floating e => DisplayRealFloat e -> DisplayRealFloat e
sinh :: DisplayRealFloat e -> DisplayRealFloat e
$ccosh :: forall e. Floating e => DisplayRealFloat e -> DisplayRealFloat e
cosh :: DisplayRealFloat e -> DisplayRealFloat e
$ctanh :: forall e. Floating e => DisplayRealFloat e -> DisplayRealFloat e
tanh :: DisplayRealFloat e -> DisplayRealFloat e
$casinh :: forall e. Floating e => DisplayRealFloat e -> DisplayRealFloat e
asinh :: DisplayRealFloat e -> DisplayRealFloat e
$cacosh :: forall e. Floating e => DisplayRealFloat e -> DisplayRealFloat e
acosh :: DisplayRealFloat e -> DisplayRealFloat e
$catanh :: forall e. Floating e => DisplayRealFloat e -> DisplayRealFloat e
atanh :: DisplayRealFloat e -> DisplayRealFloat e
$clog1p :: forall e. Floating e => DisplayRealFloat e -> DisplayRealFloat e
log1p :: DisplayRealFloat e -> DisplayRealFloat e
$cexpm1 :: forall e. Floating e => DisplayRealFloat e -> DisplayRealFloat e
expm1 :: DisplayRealFloat e -> DisplayRealFloat e
$clog1pexp :: forall e. Floating e => DisplayRealFloat e -> DisplayRealFloat e
log1pexp :: DisplayRealFloat e -> DisplayRealFloat e
$clog1mexp :: forall e. Floating e => DisplayRealFloat e -> DisplayRealFloat e
log1mexp :: DisplayRealFloat e -> 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.3.0
deriving via (ShowInstance Void) instance Display Void

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

-- | @since 0.0.1.0
-- 'displayList' is overloaded, so that when the @Display [a]@ instance calls 'displayList',
-- we end up with a nice string instead of a list of chars between brackets.
--
-- >>> display [1, 2, 3]
-- "[1,2,3]"
--
-- >>> display ['h', 'e', 'l', 'l', 'o']
-- "hello"
instance Display Char where
  -- This instance's implementation is used in the haddocks of the typeclass.
  -- If you change it, reflect the change in the documentation.
  displayBuilder :: Char -> Builder
displayBuilder Char
c = Text -> Builder
TB.fromText (Text -> Builder) -> Text -> Builder
forall a b. (a -> b) -> a -> b
$ Char -> Text
T.singleton Char
c
  displayList :: String -> Builder
displayList String
cs = Text -> Builder
TB.fromText (Text -> Builder) -> Text -> Builder
forall a b. (a -> b) -> a -> b
$ String -> Text
T.pack String
cs

-- | 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
  {-# SPECIALIZE instance Display [String] #-}
  {-# SPECIALIZE instance Display [Char] #-}
  {-# SPECIALIZE 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.