1
1
{-# LANGUAGE DataKinds #-}
2
- {-# LANGUAGE OverloadedStrings #-}
3
2
{-# LANGUAGE DerivingVia #-}
4
3
{-# LANGUAGE GeneralizedNewtypeDeriving #-}
4
+ {-# LANGUAGE OverloadedStrings #-}
5
5
{-# LANGUAGE ScopedTypeVariables #-}
6
6
{-# LANGUAGE StandaloneDeriving #-}
7
7
{-# LANGUAGE StrictData #-}
10
10
{-# LANGUAGE TypeOperators #-}
11
11
{-# LANGUAGE UndecidableInstances #-}
12
12
13
- {-|
14
- Module : Data.Text.Display
15
- Copyright : © Hécate Moonlight, 2021
16
- License : MIT
17
-
18
- Stability : stable
19
-
20
- Use 'display' to produce user-facing text
21
-
22
- -}
13
+ -- |
14
+ -- Module : Data.Text.Display
15
+ -- Copyright : © Hécate Moonlight, 2021
16
+ -- License : MIT
17
+
18
+ -- Stability : stable
19
+ --
20
+ -- Use 'display' to produce user-facing text
23
21
module Data.Text.Display
24
22
( -- * Documentation
25
23
display
26
- , Display (.. )
27
- , -- * Deriving your instance automatically
28
- ShowInstance (.. )
29
- , OpaqueInstance (.. )
30
- , -- * Writing your instance by hand
31
- displayParen
32
- -- * Design choices
33
- -- $designChoices
34
- ) where
24
+ , Display (.. )
25
+
26
+ -- * Deriving your instance automatically
27
+ , ShowInstance (.. )
28
+ , OpaqueInstance (.. )
29
+
30
+ -- * Writing your instance by hand
31
+ , displayParen
32
+
33
+ -- * Design choices
34
+ -- $designChoices
35
+ )
36
+ where
35
37
36
38
import Control.Exception hiding (TypeError )
37
39
import Data.ByteString
40
+ import qualified Data.ByteString.Lazy as BL
38
41
import Data.Int
39
42
import Data.Kind
40
43
import Data.List.NonEmpty
44
+ import Data.Proxy
41
45
import Data.Text (Text )
46
+ import qualified Data.Text as T
47
+ import qualified Data.Text.Lazy as TL
42
48
import Data.Text.Lazy.Builder (Builder )
43
- import Data.Word
44
- import GHC.TypeLits
45
- import qualified Data.ByteString.Lazy as BL
46
49
import qualified Data.Text.Lazy.Builder as TB
47
50
import qualified Data.Text.Lazy.Builder.Int as TB
48
51
import qualified Data.Text.Lazy.Builder.RealFloat as TB
49
- import qualified Data.Text as T
50
- import qualified Data.Text.Lazy as TL
51
- import Data.Proxy
52
+ import Data.Word
53
+ import GHC.TypeLits
52
54
53
55
-- | A typeclass for user-facing output.
54
56
--
55
57
-- @since 0.0.1.0
56
58
class Display a where
57
59
{-# MINIMAL displayBuilder | displayPrec #-}
60
+
58
61
-- | Implement this method to describe how to convert your value to 'Builder'.
59
62
displayBuilder :: a -> Builder
60
63
displayBuilder = displayPrec 0
@@ -91,11 +94,11 @@ class Display a where
91
94
-- > → Custom `displayList`
92
95
displayList :: [a ] -> Builder
93
96
displayList [] = " []"
94
- displayList (x: xs) = displayList' xs (" [" <> displayBuilder x)
97
+ displayList (x : xs) = displayList' xs (" [" <> displayBuilder x)
95
98
where
96
99
displayList' :: [a ] -> Builder -> Builder
97
- displayList' [] acc = acc <> " ]"
98
- displayList' (y: ys) acc = displayList' ys (acc <> " ," <> displayBuilder y)
100
+ displayList' [] acc = acc <> " ]"
101
+ displayList' (y : ys) acc = displayList' ys (acc <> " ," <> displayBuilder y)
99
102
100
103
-- | The method 'displayPrec' allows you to write instances that
101
104
-- require nesting. The precedence parameter can be thought of as a
@@ -127,13 +130,13 @@ class Display a where
127
130
-- > infix 5 :*: -- arbitrary choice of precedence
128
131
-- > instance (Display a, Display b) => Display (Pair a b) where
129
132
-- > displayPrec prec (a :*: b) = displayParen (prec > 5) $ displayPrec 6 a <> " :*: " <> displayPrec 6 b
130
- displayPrec
131
- :: Int -- ^ The precedence level passed in by the surrounding context
132
- -> a
133
- -> Builder
133
+ displayPrec ::
134
+ -- | The precedence level passed in by the surrounding context
135
+ Int ->
136
+ a ->
137
+ Builder
134
138
displayPrec _ = displayBuilder
135
139
136
-
137
140
-- | Convert a value to a readable 'Text'.
138
141
--
139
142
-- === Examples
@@ -159,12 +162,13 @@ instance CannotDisplayBareFunctions => Display (a -> b) where
159
162
160
163
-- | @since 0.0.1.0
161
164
type family CannotDisplayBareFunctions :: Constraint where
162
- CannotDisplayBareFunctions = TypeError
163
- ( 'Text " 🚫 You should not try to display functions!" ':$$:
164
- 'Text " 💡 Write a 'newtype' wrapper that represents your domain more accurately." ':$$:
165
- 'Text " If you are not consciously trying to use `display` on a function," ':$$:
166
- 'Text " make sure that you are not missing an argument somewhere."
167
- )
165
+ CannotDisplayBareFunctions =
166
+ TypeError
167
+ ( 'Text " 🚫 You should not try to display functions!"
168
+ ':$$: 'Text " 💡 Write a 'newtype' wrapper that represents your domain more accurately."
169
+ ':$$: 'Text " If you are not consciously trying to use `display` on a function,"
170
+ ':$$: 'Text " make sure that you are not missing an argument somewhere."
171
+ )
168
172
169
173
-- | 🚫 You should not try to display strict ByteStrings!
170
174
--
@@ -185,11 +189,12 @@ instance CannotDisplayByteStrings => Display BL.ByteString where
185
189
displayBuilder = undefined
186
190
187
191
type family CannotDisplayByteStrings :: Constraint where
188
- CannotDisplayByteStrings = TypeError
189
- ( 'Text " 🚫 You should not try to display ByteStrings!" ':$$:
190
- 'Text " 💡 Always provide an explicit encoding" ':$$:
191
- 'Text " Use 'Data.Text.Encoding.decodeUtf8'' or 'Data.Text.Encoding.decodeUtf8With' to convert from UTF-8"
192
- )
192
+ CannotDisplayByteStrings =
193
+ TypeError
194
+ ( 'Text " 🚫 You should not try to display ByteStrings!"
195
+ ':$$: 'Text " 💡 Always provide an explicit encoding"
196
+ ':$$: 'Text " Use 'Data.Text.Encoding.decodeUtf8'' or 'Data.Text.Encoding.decodeUtf8With' to convert from UTF-8"
197
+ )
193
198
194
199
-- | A utility function that surrounds the given 'Builder' with parentheses when the Bool parameter is True.
195
200
-- Useful for writing instances that may require nesting. See the 'displayPrec' documentation for more
@@ -237,7 +242,8 @@ instance KnownSymbol str => Display (OpaqueInstance str a) where
237
242
newtype ShowInstance (a :: Type )
238
243
= ShowInstance a
239
244
deriving newtype
240
- ( Show -- ^ @since 0.0.1.0
245
+ ( -- | @since 0.0.1.0
246
+ Show
241
247
)
242
248
243
249
-- | This wrapper allows you to rely on a pre-existing 'Show' instance in order to derive 'Display' from it.
@@ -301,9 +307,10 @@ instance Display Text where
301
307
302
308
-- | @since 0.0.1.0
303
309
instance Display a => Display [a ] where
304
- {-# SPECIALISE instance Display [String] #-}
305
- {-# SPECIALISE instance Display [Char] #-}
306
- {-# SPECIALISE instance Display [Int] #-}
310
+ {-# SPECIALIZE instance Display [String] #-}
311
+ {-# SPECIALIZE instance Display [Char] #-}
312
+ {-# SPECIALIZE instance Display [Int] #-}
313
+
307
314
-- In this instance, 'displayBuilder' is defined in terms of 'displayList', which for most types
308
315
-- is defined as the default written in the class declaration.
309
316
-- But when @a ~ Char@, there is an explicit implementation that is selected instead, which
@@ -373,15 +380,15 @@ deriving via (ShowInstance SomeException) instance Display SomeException
373
380
374
381
-- | @since 0.0.1.0
375
382
instance (Display a , Display b ) => Display (a , b ) where
376
- displayBuilder (a, b) = " (" <> displayBuilder a <> " ," <> displayBuilder b <> " )"
383
+ displayBuilder (a, b) = " (" <> displayBuilder a <> " ," <> displayBuilder b <> " )"
377
384
378
385
-- | @since 0.0.1.0
379
386
instance (Display a , Display b , Display c ) => Display (a , b , c ) where
380
- displayBuilder (a, b, c) = " (" <> displayBuilder a <> " ," <> displayBuilder b <> " ," <> displayBuilder c <> " )"
387
+ displayBuilder (a, b, c) = " (" <> displayBuilder a <> " ," <> displayBuilder b <> " ," <> displayBuilder c <> " )"
381
388
382
389
-- | @since 0.0.1.0
383
390
instance (Display a , Display b , Display c , Display d ) => Display (a , b , c , d ) where
384
- displayBuilder (a, b, c, d) = " (" <> displayBuilder a <> " ," <> displayBuilder b <> " ," <> displayBuilder c <> " ," <> displayBuilder d <> " )"
391
+ displayBuilder (a, b, c, d) = " (" <> displayBuilder a <> " ," <> displayBuilder b <> " ," <> displayBuilder c <> " ," <> displayBuilder d <> " )"
385
392
386
393
-- $designChoices
387
394
--
0 commit comments