Skip to content

Commit 916e009

Browse files
authored
Remove array allocation and local array ffi from the Show instance for records (#299)
* Don't allocate an array to show a record * Update changelog * Simplify the code
1 parent f411f34 commit 916e009

File tree

6 files changed

+28
-32
lines changed

6 files changed

+28
-32
lines changed

CHANGELOG.md

+1
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ Bugfixes:
1212

1313
Other improvements:
1414
- Documentation: Clarify relationship between `Ord` and `Eq` (#298 by @JamieBallingall)
15+
- Remove array allocation and local array FFI from the `Show` instance for records. (#299 by @ajnsit)
1516

1617
## [v6.0.0](https://github.com/purescript/purescript-prelude/releases/tag/v6.0.0) - 2022-04-27
1718

src/Data/Show.js

-12
Original file line numberDiff line numberDiff line change
@@ -57,15 +57,3 @@ export const showArrayImpl = function (f) {
5757
return "[" + ss.join(",") + "]";
5858
};
5959
};
60-
61-
export const cons = function (head) {
62-
return function (tail) {
63-
return [head].concat(tail);
64-
};
65-
};
66-
67-
export const intercalate = function (separator) {
68-
return function (xs) {
69-
return xs.join(separator);
70-
};
71-
};

src/Data/Show.purs

+24-9
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,10 @@ module Data.Show
55
, showRecordFields
66
) where
77

8+
import Data.Semigroup ((<>))
89
import Data.Symbol (class IsSymbol, reflectSymbol)
10+
import Data.Unit (Unit)
11+
import Data.Void (Void, absurd)
912
import Prim.Row (class Nub)
1013
import Prim.RowList as RL
1114
import Record.Unsafe (unsafeGet)
@@ -20,6 +23,9 @@ import Type.Proxy (Proxy(..))
2023
class Show a where
2124
show :: a -> String
2225

26+
instance showUnit :: Show Unit where
27+
show _ = "unit"
28+
2329
instance showBoolean :: Show Boolean where
2430
show true = "true"
2531
show false = "false"
@@ -42,32 +48,43 @@ instance showArray :: Show a => Show (Array a) where
4248
instance showProxy :: Show (Proxy a) where
4349
show _ = "Proxy"
4450

51+
instance showVoid :: Show Void where
52+
show = absurd
53+
4554
instance showRecord ::
4655
( Nub rs rs
4756
, RL.RowToList rs ls
4857
, ShowRecordFields ls rs
4958
) =>
5059
Show (Record rs) where
51-
show record = case showRecordFields (Proxy :: Proxy ls) record of
52-
[] -> "{}"
53-
fields -> intercalate " " [ "{", intercalate ", " fields, "}" ]
60+
show record = "{" <> showRecordFields (Proxy :: Proxy ls) record <> "}"
5461

5562
-- | A class for records where all fields have `Show` instances, used to
5663
-- | implement the `Show` instance for records.
5764
class ShowRecordFields :: RL.RowList Type -> Row Type -> Constraint
5865
class ShowRecordFields rowlist row where
59-
showRecordFields :: Proxy rowlist -> Record row -> Array String
66+
showRecordFields :: Proxy rowlist -> Record row -> String
6067

6168
instance showRecordFieldsNil :: ShowRecordFields RL.Nil row where
62-
showRecordFields _ _ = []
63-
69+
showRecordFields _ _ = ""
70+
else
71+
instance showRecordFieldsConsNil ::
72+
( IsSymbol key
73+
, Show focus
74+
) =>
75+
ShowRecordFields (RL.Cons key focus RL.Nil) row where
76+
showRecordFields _ record = " " <> key <> ": " <> show focus <> " "
77+
where
78+
key = reflectSymbol (Proxy :: Proxy key)
79+
focus = unsafeGet key record :: focus
80+
else
6481
instance showRecordFieldsCons ::
6582
( IsSymbol key
6683
, ShowRecordFields rowlistTail row
6784
, Show focus
6885
) =>
6986
ShowRecordFields (RL.Cons key focus rowlistTail) row where
70-
showRecordFields _ record = cons (intercalate ": " [ key, show focus ]) tail
87+
showRecordFields _ record = " " <> key <> ": " <> show focus <> "," <> tail
7188
where
7289
key = reflectSymbol (Proxy :: Proxy key)
7390
focus = unsafeGet key record :: focus
@@ -78,5 +95,3 @@ foreign import showNumberImpl :: Number -> String
7895
foreign import showCharImpl :: Char -> String
7996
foreign import showStringImpl :: String -> String
8097
foreign import showArrayImpl :: forall a. (a -> String) -> Array a -> String
81-
foreign import cons :: forall a. a -> Array a -> Array a
82-
foreign import intercalate :: String -> Array String -> String

src/Data/Unit.purs

-5
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,5 @@
11
module Data.Unit where
22

3-
import Data.Show (class Show)
4-
53
-- | The `Unit` type has a single inhabitant, called `unit`. It represents
64
-- | values with no computational content.
75
-- |
@@ -14,6 +12,3 @@ foreign import data Unit :: Type
1412

1513
-- | `unit` is the sole inhabitant of the `Unit` type.
1614
foreign import unit :: Unit
17-
18-
instance showUnit :: Show Unit where
19-
show _ = "unit"

src/Data/Void.purs

-5
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,5 @@
11
module Data.Void (Void, absurd) where
22

3-
import Data.Show (class Show)
4-
53
-- | An uninhabited data type. In other words, one can never create
64
-- | a runtime value of type `Void` because no such value exists.
75
-- |
@@ -21,9 +19,6 @@ import Data.Show (class Show)
2119
-- | the `void` of C-family languages above.
2220
newtype Void = Void Void
2321

24-
instance showVoid :: Show Void where
25-
show = absurd
26-
2722
-- | Eliminator for the `Void` type.
2823
-- | Useful for stating that some code branch is impossible because you've
2924
-- | "acquired" a value of type `Void` (which you can't).

test/Test/Main.purs

+3-1
Original file line numberDiff line numberDiff line change
@@ -124,7 +124,9 @@ testRecordInstances :: AlmostEff
124124
testRecordInstances = do
125125
assert "Record equality" $ { a: 1 } == { a: 1 }
126126
assert "Record inequality" $ { a: 2 } /= { a: 1 }
127-
assert "Record show" $ show { a: 1 } == "{ a: 1 }"
127+
assert "Record show nil" $ show { } == "{}"
128+
assert "Record show one" $ show { a: 1 } == "{ a: 1 }"
129+
assert "Record show more" $ show { a: 1, b: 2 } == "{ a: 1, b: 2 }"
128130
assert "Record +" $ ({ a: 1, b: 2.0 } + { a: 0, b: (-2.0) }) == { a: 1, b: 0.0 }
129131
assert "Record *" $ ({ a: 1, b: 2.0 } * { a: 0, b: (-2.0) }) == { a: 0, b: -4.0 }
130132
assert "Record one" $ one == { a: 1, b: 1.0 }

0 commit comments

Comments
 (0)