-
Notifications
You must be signed in to change notification settings - Fork 36
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Lifted Pretty classes #40
base: master
Are you sure you want to change the base?
Changes from 40 commits
5595ce0
d3a44cf
00f7bb3
c51c52b
8082325
2247b13
96e21f9
680d6e2
f8e3343
3f65702
73dd98c
6d8d0af
7cafb33
9579404
add8798
ba7ba56
146ab16
12ebec7
8f3c306
223b7af
6280232
00612b7
5acdc82
df98809
4c42bd0
fce219b
85d57e4
9d2f6a8
943163a
03bd952
566b0dc
2fa9adc
21a3c33
605f59a
ad6f171
07986b7
1da038b
f91663a
ee66301
ec0e482
fc5efc1
a60ab84
d6c2166
2441649
2284f72
d9425eb
5b9f66b
4dced20
31cf99b
03a1ae2
a1d6c13
234154c
d80a5e5
821a8f5
12457a8
dba8a03
b36e306
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -328,6 +328,15 @@ instance Pretty a => Pretty (Maybe a) where | |
pretty = maybe mempty pretty | ||
prettyList = prettyList . catMaybes | ||
|
||
-- | Print 'Left' and 'Right' contents. | ||
-- | ||
-- >>> pretty (Left True :: Either Bool Bool) | ||
-- True | ||
-- >>> pretty (Right True :: Either Bool Bool) | ||
-- True | ||
instance (Pretty a, Pretty b) => Pretty (Either a b) where | ||
pretty = either pretty pretty | ||
|
||
-- | Automatically converts all newlines to @'line'@. | ||
-- | ||
-- >>> pretty ("hello\nworld" :: Text) | ||
|
@@ -352,7 +361,95 @@ instance Pretty Lazy.Text where pretty = pretty . Lazy.toStrict | |
-- [] | ||
instance Pretty Void where pretty = absurd | ||
|
||
-- | Overloaded conversion to 'Doc', lifted to unary type constructors. | ||
-- | ||
-- This is most useful for: | ||
-- 1. defining 'Pretty' instances for recursive types, | ||
-- 2. defining 'Pretty' instances for type constructors without 'Functor' | ||
-- instances, and | ||
-- 3. efficiently pretty-printing type constructors with 'Functor' instances | ||
-- whose 'fmap' traverses the whole structure. | ||
-- | ||
-- Laws: | ||
-- | ||
-- 1. output should be pretty. :-) | ||
class Pretty1 f where | ||
|
||
-- | >>> liftPretty (parens . pretty) (list . map (parens . pretty)) (Just "hello") | ||
-- (hello) | ||
liftPretty | ||
:: (a -> Doc ann) -- ^ A function to print a single value. | ||
-> ([a] -> Doc ann) -- ^ A function to print a list. Used for []. | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Is this really necessary? It clutters the definitions quite a bit, but it’s usually just There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It’s necessary for the There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Arrr, I see. Actually, this brings up a new law: |
||
-> f a | ||
-> Doc ann | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It turns out that there’s nothing gained by providing
liftPrettyList pretty' prettyList' = list . map (liftPretty pretty' prettyList') |
||
|
||
-- | >>> liftPretty (parens . pretty) (list . map (parens . pretty)) [1,2,3] | ||
-- [(1), (2), (3)] | ||
instance Pretty1 [] where | ||
liftPretty _ prettyList' = prettyList' | ||
|
||
instance Pretty1 NonEmpty where | ||
liftPretty _ prettyList' (x:|xs) = prettyList' (x:xs) | ||
|
||
-- | Ignore 'Nothing's, print 'Just' contents with the supplied function. | ||
-- | ||
-- >>> liftPretty (parens . pretty) (list . map (parens . pretty)) (Just True) | ||
-- (True) | ||
-- >>> braces (liftPretty (parens . pretty) (list . map (parens . pretty)) (Nothing :: Maybe Bool)) | ||
-- {} | ||
instance Pretty1 Maybe where | ||
liftPretty prettyJust _ = maybe mempty prettyJust | ||
|
||
-- | Print 'Left' contents with 'pretty', and 'Right' contents with the supplied | ||
-- function. | ||
-- | ||
-- >>> liftPretty (parens . pretty) (list . map (parens . pretty)) (Left True :: Either Bool Bool) | ||
-- True | ||
-- >>> liftPretty (parens . pretty) (list . map (parens . pretty)) (Right True :: Either Bool Bool) | ||
-- (True) | ||
instance Pretty a => Pretty1 (Either a) where | ||
liftPretty prettyRight _ = either pretty prettyRight | ||
|
||
-- | >>> liftPretty (parens . pretty) (list . map (parens . pretty)) (123, "hello") | ||
-- (123, (hello)) | ||
instance Pretty a => Pretty1 ((,) a) where | ||
liftPretty pretty2 _ (x1, x2) = tupled [pretty x1, pretty2 x2] | ||
|
||
-- | Overloaded conversion to 'Doc', lifted to binary type constructors. | ||
-- | ||
-- This is most useful for: | ||
-- 1. defining 'Pretty' instances for recursive types, | ||
-- 2. defining 'Pretty' instances for type constructors without 'Functor' | ||
-- instances, and | ||
-- 3. efficiently pretty-printing type constructors with 'Functor' instances | ||
-- whose 'fmap' traverses the whole structure. | ||
-- | ||
-- Laws: | ||
-- | ||
-- 1. output should be pretty. :-) | ||
class Pretty2 f where | ||
|
||
liftPretty2 | ||
:: (a -> Doc ann) -- ^ A function to print a single value of the first parameter. | ||
-> ([a] -> Doc ann) -- ^ A function to print a list of the first parameter. | ||
-> (b -> Doc ann) -- ^ A function to print a single value of the second parameter. | ||
-> ([b] -> Doc ann) -- ^ A function to print a list of the second parameter. | ||
-> f a b | ||
-> Doc ann | ||
|
||
-- | Print 'Left' and 'Right' contents with the supplied functions. | ||
-- | ||
-- >>> liftPretty2 (parens . pretty) (list . map (parens . pretty)) (parens . pretty) (list . map (parens . pretty)) (Left True :: Either Bool Bool) | ||
-- (True) | ||
-- >>> liftPretty2 (parens . pretty) (list . map (parens . pretty)) (parens . pretty) (list . map (parens . pretty)) (Right True :: Either Bool Bool) | ||
-- (True) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. These doctests are unfortunately quite lengthy, but it’s a little difficult providing good concise examples for nonrecursive types. Nevertheless, I’ve found these instances to be quite useful in practice, so I felt it was worth providing them, lengthy doctests and all. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think these tests would be nicer if they weren’t on a single line, but with |
||
instance Pretty2 Either where | ||
liftPretty2 prettyLeft _ prettyRight _ = either prettyLeft prettyRight | ||
|
||
-- | >>> liftPretty2 (parens . pretty) (list . map (parens . pretty)) (parens . pretty) (list . map (parens . pretty)) (123, "hello") | ||
-- ((123), (hello)) | ||
instance Pretty2 (,) where | ||
liftPretty2 pretty1 _ pretty2 _ (x1, x2) = tupled [pretty1 x1, pretty2 x2] | ||
|
||
-- | @(unsafeTextWithoutNewlines s)@ contains the literal string @s@. | ||
-- | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think there should be an example for an instance definition here, for example the
[]
one. And the law joke doesn’t need to be repeated again ;-)I think the key to the Pretty1 documentation should be showing how it is useful without going into too much detail. Like »here we define Pretty without using Pretty1, see how Pretty1 makes our lives much easier?«