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

-- |
--  Module      : Data.Text.Display.Core
--  Copyright   : © Hécate Moonlight, 2021
--  License     : MIT
--  Maintainer  : hecate@glitchbra.in
--  Stability   : stable
--
--  Core 'Display' typeclass and instances
module Data.Text.Display.Core 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 = 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
"[" forall a. Semigroup a => a -> a -> a
<> forall a. Display a => a -> Builder
displayBuilder a
x forall a. Semigroup a => a -> a -> a
<> forall (t :: * -> *) m a.
(Foldable t, Monoid m) =>
(a -> m) -> t a -> m
foldMap a -> Builder
go [a]
xs forall a. Semigroup a => a -> a -> a
<> Builder
"]"
    where
      go :: a -> Builder
      go :: a -> Builder
go a
y = Builder
"," forall a. Semigroup a => a -> a -> a
<> 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
_ = 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 forall a b. (a -> b) -> a -> b
$ Builder -> Text
TB.toLazyText forall a b. (a -> b) -> a -> b
$ 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 = 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 = 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 = 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
"(" forall a. Semigroup a => a -> a -> a
<> Builder
txt 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 forall a b. (a -> b) -> a -> b
$ forall (n :: Symbol) (proxy :: Symbol -> *).
KnownSymbol n =>
proxy n -> String
symbolVal (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
    ( Int -> ShowInstance a -> ShowS
[ShowInstance a] -> ShowS
ShowInstance a -> String
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
showList :: [ShowInstance a] -> ShowS
$cshowList :: forall a. Show a => [ShowInstance a] -> ShowS
show :: ShowInstance a -> String
$cshow :: forall a. Show a => ShowInstance a -> String
showsPrec :: Int -> ShowInstance a -> ShowS
$cshowsPrec :: forall a. Show a => Int -> 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 forall a b. (a -> b) -> a -> b
$ forall a. Show a => a -> String
show ShowInstance e
s

-- @since 0.0.1.0
newtype DisplayDecimal e
  = DisplayDecimal e
  deriving newtype
    (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
Integral, 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
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]
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, 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
Ord, Integer -> DisplayDecimal e
DisplayDecimal e -> DisplayDecimal e
DisplayDecimal e -> DisplayDecimal e -> 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
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 = forall a. Integral a => a -> Builder
TB.decimal

-- @since 0.0.1.0
newtype DisplayRealFloat e
  = DisplayRealFloat e
  deriving newtype
    (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
RealFloat, 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 :: forall b. Integral b => DisplayRealFloat e -> b
$cfloor :: forall e b. (RealFrac e, Integral b) => DisplayRealFloat e -> b
ceiling :: forall b. Integral b => DisplayRealFloat e -> b
$cceiling :: forall e b. (RealFrac e, Integral b) => DisplayRealFloat e -> b
round :: forall b. Integral b => DisplayRealFloat e -> b
$cround :: forall e b. (RealFrac e, Integral b) => DisplayRealFloat e -> b
truncate :: forall b. Integral b => DisplayRealFloat e -> b
$ctruncate :: forall e b. (RealFrac e, Integral b) => DisplayRealFloat e -> b
properFraction :: forall b.
Integral b =>
DisplayRealFloat e -> (b, DisplayRealFloat e)
$cproperFraction :: forall e b.
(RealFrac e, Integral b) =>
DisplayRealFloat e -> (b, DisplayRealFloat e)
RealFrac, 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
Real, 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
Ord, DisplayRealFloat e -> DisplayRealFloat e -> Bool
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
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, 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
Fractional, 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
Floating)

-- @since 0.0.1.0
instance RealFloat e => Display (DisplayRealFloat e) where
  displayBuilder :: DisplayRealFloat e -> Builder
displayBuilder = 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 forall a b. (a -> b) -> a -> b
$ Char -> Text
T.singleton Char
c
  displayList :: String -> Builder
displayList String
cs = Text -> Builder
TB.fromText 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 = 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) = forall a. Display a => a -> Builder
displayBuilder a
a forall a. Semigroup a => a -> a -> a
<> String -> Builder
TB.fromString String
" :| " forall a. Semigroup a => a -> a -> a
<> 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 forall a. Ord a => a -> a -> Bool
> Int
10) forall a b. (a -> b) -> a -> b
$ Builder
"Just " forall a. Semigroup a => a -> a -> a
<> 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
"(" forall a. Semigroup a => a -> a -> a
<> forall a. Display a => a -> Builder
displayBuilder a
a forall a. Semigroup a => a -> a -> a
<> Builder
"," forall a. Semigroup a => a -> a -> a
<> forall a. Display a => a -> Builder
displayBuilder b
b 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
"(" forall a. Semigroup a => a -> a -> a
<> forall a. Display a => a -> Builder
displayBuilder a
a forall a. Semigroup a => a -> a -> a
<> Builder
"," forall a. Semigroup a => a -> a -> a
<> forall a. Display a => a -> Builder
displayBuilder b
b forall a. Semigroup a => a -> a -> a
<> Builder
"," forall a. Semigroup a => a -> a -> a
<> forall a. Display a => a -> Builder
displayBuilder c
c 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
"(" forall a. Semigroup a => a -> a -> a
<> forall a. Display a => a -> Builder
displayBuilder a
a forall a. Semigroup a => a -> a -> a
<> Builder
"," forall a. Semigroup a => a -> a -> a
<> forall a. Display a => a -> Builder
displayBuilder b
b forall a. Semigroup a => a -> a -> a
<> Builder
"," forall a. Semigroup a => a -> a -> a
<> forall a. Display a => a -> Builder
displayBuilder c
c forall a. Semigroup a => a -> a -> a
<> Builder
"," forall a. Semigroup a => a -> a -> a
<> forall a. Display a => a -> Builder
displayBuilder d
d 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.