Skip to content

Commit 05c8fdd

Browse files
committed
Change Show-instances to use "#field := val"
The previous show instance would add another layer of quoting for each nesting: ``` ghci> show (rcons (#foo := "bar") rnil) "[(\"foo\",\"\\\"bar\\\"\")]" ``` Instead, what we want is to display a nicely readable variant of the record, using the infix field syntax for both label/value pairs and full records: ``` ghci> show (rcons (#hi := (rcons (#lea := "hi") rnil)) (rcons (#foo := "bar") rnil )) "[#foo := \"bar\",#hi := [(#lea := \"hi\")]]" ghci> show (#hi := "lea") "#hi := \"lea\"" ``` That’s better! Note that we can’t have a roundtripping `Read` instance anyway, so we might as well have `Show` be readable. Fixes #36
1 parent 5a7d686 commit 05c8fdd

3 files changed

Lines changed: 16 additions & 4 deletions

File tree

src/SuperRecord.hs

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -101,6 +101,7 @@ import Data.Kind (Type)
101101

102102
#if MIN_VERSION_aeson(2, 0, 0)
103103
import qualified Data.Aeson.Key as Key
104+
import Text.Show (showListWith)
104105
#else
105106
import qualified Data.Text as T
106107
#endif
@@ -160,7 +161,7 @@ class ( c1 k a b, c2 k a b ) => Tuple222C c1 c2 k a b
160161
instance ( c1 k a b, c2 k a b ) => Tuple222C c1 c2 k a b
161162

162163
instance (RecApply lts lts (ConstC Show)) => Show (Rec lts) where
163-
show = show . showRec
164+
showsPrec = showsPrecRec
164165

165166
instance RecApply lts lts (Tuple22C (ConstC Eq) (Has lts)) => Eq (Rec lts) where
166167
r1 == r2 = recApply @lts @lts @(Tuple22C (ConstC Eq) (Has lts)) ( \lbl v b -> get lbl r2 == v && b ) r1 True
@@ -712,6 +713,13 @@ reflectRecFold f r =
712713
showRec :: forall lts. (RecApply lts lts (ConstC Show)) => Rec lts -> [(String, String)]
713714
showRec = reflectRec @(ConstC Show) (\(_ :: FldProxy lbl) v -> (symbolVal' (proxy# :: Proxy# lbl), show v))
714715

716+
showsPrecRec :: forall lts. (RecApply lts lts (ConstC Show)) => Int -> Rec lts -> ShowS
717+
showsPrecRec d r =
718+
showListWith id $
719+
reflectRec
720+
@(ConstC Show) (\(lbl :: FldProxy lbl) v -> showsPrec (d+1) (lbl := v))
721+
r
722+
715723
recToValue :: forall lts. (RecApply lts lts (ConstC ToJSON)) => Rec lts -> Value
716724
recToValue r = object $ reflectRec @(ConstC ToJSON) (\(_ :: FldProxy lbl) v -> (jsonKey $ symbolVal' (proxy# :: Proxy# lbl), toJSON v)) r
717725

src/SuperRecord/Field.hs

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -29,8 +29,12 @@ instance (Ord value) => Ord (label := value) where
2929

3030
instance (Show t) =>
3131
Show (l := t) where
32-
showsPrec p (l := t) =
33-
showParen (p > 10) (showString ("#" ++ symbolVal l ++ " := " ++ show t))
32+
showsPrec d (l := t) =
33+
showParen (d > labelPrec) $
34+
showString ("#" ++ symbolVal l ++ " := ")
35+
. showsPrec (labelPrec+1) t
36+
where
37+
labelPrec = 6
3438

3539
-- | A proxy witness for a label. Very similar to 'Proxy', but needed to implement
3640
-- a non-orphan 'IsLabel' instance

test/Spec.hs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -351,7 +351,7 @@ recordTests =
351351
do let vals = showRec r1
352352
vals `shouldBe` [("foo", "\"Hi\""), ("int", "213")]
353353
it "show works" $
354-
show r1 `shouldBe` "[(\"foo\",\"\\\"Hi\\\"\"),(\"int\",\"213\")]"
354+
show r1 `shouldBe` "[#foo := \"Hi\",#int := 213]"
355355
it "equality works" $
356356
do r1 == r1 `shouldBe` True
357357
r1 == set #foo "Hai" r1 `shouldBe` False

0 commit comments

Comments
 (0)