Skip to content
This repository was archived by the owner on Jun 15, 2023. It is now read-only.

Commit 237bc59

Browse files
authored
Merge pull request #16 from garyb/comparisons
Fix `Ord` / `Ord1` by restoring original `Ord1` instance
2 parents 01feced + df1e9b3 commit 237bc59

File tree

7 files changed

+149
-144
lines changed

7 files changed

+149
-144
lines changed

src/Data/Json/Extended.purs

+4-4
Original file line numberDiff line numberDiff line change
@@ -146,10 +146,10 @@ array ∷ ∀ t. Corecursive t Sig.EJsonF ⇒ Array t → t
146146
array = embed <<< Sig.Array
147147

148148
map t. Corecursive t Sig.EJsonF Map.Map t t t
149-
map = embed <<< Sig.Map <<< A.fromFoldable <<< Map.toList
149+
map = embed <<< Sig.Map <<< Sig.EJsonMap <<< A.fromFoldable <<< Map.toList
150150

151151
map' t. Corecursive t Sig.EJsonF SM.StrMap t t
152-
map' = embed <<< Sig.Map <<< F.map go <<< A.fromFoldable <<< SM.toList
152+
map' = embed <<< Sig.Map <<< Sig.EJsonMap <<< F.map go <<< A.fromFoldable <<< SM.toList
153153
where
154154
go (T.Tuple a b) = T.Tuple (string a) b
155155

@@ -213,10 +213,10 @@ _Array = prism' array $ project >>> case _ of
213213

214214
_Map t. (Corecursive t Sig.EJsonF, Recursive t Sig.EJsonF, Ord t) Prism' t (Map.Map t t)
215215
_Map = prism' map $ project >>> case _ of
216-
Sig.Map kvs → M.Just $ Map.fromFoldable kvs
216+
Sig.Map (Sig.EJsonMap kvs)M.Just $ Map.fromFoldable kvs
217217
_ → M.Nothing
218218

219219
_Map' t. (Corecursive t Sig.EJsonF, Recursive t Sig.EJsonF) Prism' t (SM.StrMap t)
220220
_Map' = prism' map' $ project >>> case _ of
221-
Sig.Map kvs → SM.fromFoldable <$> for kvs (bitraverse (preview _String) pure)
221+
Sig.Map (Sig.EJsonMap kvs)SM.fromFoldable <$> for kvs (bitraverse (preview _String) pure)
222222
_ → M.Nothing

src/Data/Json/Extended/Cursor.purs

+3-3
Original file line numberDiff line numberDiff line change
@@ -105,7 +105,7 @@ set cur x v = case lmap project <$> peel cur of
105105
-- | ```
106106
getKey EJ.EJson EJ.EJson Maybe EJ.EJson
107107
getKey k v = case project v of
108-
EJ.Map fields → lookup k fields
108+
EJ.Map (EJ.EJsonMap fields) → lookup k fields
109109
_ → Nothing
110110

111111
-- | For a given key, attempts to set a new value for it in an EJson Map. If the
@@ -120,8 +120,8 @@ getKey k v = case project v of
120120
-- | ```
121121
setKey EJ.EJson EJ.EJson EJ.EJson EJ.EJson
122122
setKey k x v = case project v of
123-
EJ.Map fields →
124-
embed <<< EJ.Map $ map
123+
EJ.Map (EJ.EJsonMap fields)
124+
embed <<< EJ.Map <<< EJ.EJsonMap $ map
125125
(\(kv@(Tuple k' v)) → if k == k' then Tuple k x else kv) fields
126126
_ → v
127127

+57-76
Original file line numberDiff line numberDiff line change
@@ -1,23 +1,25 @@
11
module Data.Json.Extended.Signature.Core
22
( EJsonF(..)
3+
, EJsonMap(..)
34
, getType
45
) where
56

67
import Prelude
78

89
import Data.Bifunctor as BF
910
import Data.DateTime as DT
10-
import Data.Eq (class Eq1, eq1)
11+
import Data.Eq (class Eq1)
1112
import Data.Foldable as F
1213
import Data.HugeNum as HN
13-
import Data.Int as Int
1414
import Data.Json.Extended.Type as JT
1515
import Data.List as L
16+
import Data.Map as M
1617
import Data.Monoid (mempty)
18+
import Data.Newtype (class Newtype)
1719
import Data.Ord (class Ord1)
20+
import Data.TacitString (TacitString)
1821
import Data.Traversable as T
1922
import Data.Tuple (Tuple(..))
20-
import Data.TacitString (TacitString)
2123

2224
-- | The signature endofunctor for the EJson theory.
2325
data EJsonF a
@@ -32,42 +34,34 @@ data EJsonF a
3234
| Interval String
3335
| ObjectId String
3436
| Array (Array a)
35-
| Map (Array (Tuple a a))
36-
37-
instance functorEJsonFFunctor EJsonF where
38-
map f x =
39-
case x of
40-
NullNull
41-
String str → String str
42-
Boolean b → Boolean b
43-
Integer i → Integer i
44-
Decimal a → Decimal a
45-
Timestamp ts → Timestamp ts
46-
Date d → Date d
47-
Time t → Time t
48-
Interval i → Interval i
49-
ObjectId oid → ObjectId oid
50-
Array xs → Array $ f <$> xs
51-
Map xs → Map $ BF.bimap f f <$> xs
37+
| Map (EJsonMap a)
38+
39+
derive instance functorEJsonFFunctor EJsonF
40+
41+
derive instance eqEJsonFEq a Eq (EJsonF a)
42+
instance eq1EJsonFEq1 EJsonF where eq1 = eq
43+
44+
derive instance ordEJsonFOrd a Ord (EJsonF a)
45+
instance ord1EJsonFOrd1 EJsonF where compare1 = compare
5246

5347
instance foldableEJsonFF.Foldable EJsonF where
5448
foldMap f = case _ of
5549
Array xs → F.foldMap f xs
56-
Map xs → F.foldMap (\(Tuple k v) → f k <> f v) xs
50+
Map xs → F.foldMap f xs
5751
_ → mempty
5852
foldl f a = case _ of
5953
Array xs → F.foldl f a xs
60-
Map xs → F.foldl (\acc (Tuple k v) → f (f acc k) v) a xs
54+
Map xs → F.foldl f a xs
6155
_ → a
6256
foldr f a = case _ of
6357
Array xs → F.foldr f a xs
64-
Map xs → F.foldr (\(Tuple k v) acc → f k $ f v acc) a xs
58+
Map xs → F.foldr f a xs
6559
_ → a
6660

6761
instance traversableEJsonFT.Traversable EJsonF where
6862
traverse f = case _ of
69-
Array xs → map Array $ T.traverse f xs
70-
Map xs → map Map $ T.traverse (\(Tuple k v) → Tuple <$> f k <*> f v) xs
63+
Array xs → Array <$> T.traverse f xs
64+
Map xs → Map <$> T.traverse f xs
7165
Null → pure Null
7266
String str → pure $ String str
7367
Boolean b → pure $ Boolean b
@@ -80,57 +74,6 @@ instance traversableEJsonF ∷ T.Traversable EJsonF where
8074
ObjectId oid → pure $ ObjectId oid
8175
sequence = T.sequenceDefault
8276

83-
instance eq1EJsonFEq1 EJsonF where
84-
eq1 Null Null = true
85-
eq1 (Boolean b1) (Boolean b2) = b1 == b2
86-
eq1 (Integer i) (Integer j) = i == j
87-
eq1 (Decimal a) (Decimal b) = a == b
88-
eq1 (Integer i) (Decimal b) = intToHugeNum i == b
89-
eq1 (Decimal a) (Integer j) = a == intToHugeNum j
90-
eq1 (String a) (String b) = a == b
91-
eq1 (Timestamp a) (Timestamp b) = a == b
92-
eq1 (Date a) (Date b) = a == b
93-
eq1 (Time a) (Time b) = a == b
94-
eq1 (Interval a) (Interval b) = a == b
95-
eq1 (ObjectId a) (ObjectId b) = a == b
96-
eq1 (Array xs) (Array ys) = xs == ys
97-
eq1 (Map xs) (Map ys) =
98-
let
99-
xs' = L.fromFoldable xs
100-
ys' = L.fromFoldable ys
101-
in
102-
isSubobject xs' ys'
103-
&& isSubobject ys' xs'
104-
eq1 _ _ = false
105-
106-
instance eqEJsonFEq a Eq (EJsonF a) where
107-
eq = eq1
108-
109-
-- | Very badly performing, but we don't have access to Ord here,
110-
-- | so the performant version is not implementable.
111-
isSubobject
112-
a b
113-
. (Eq a, Eq b)
114-
L.List (Tuple a b)
115-
L.List (Tuple a b)
116-
Boolean
117-
isSubobject xs ys =
118-
F.foldl
119-
(\acc x → acc && F.elem x ys)
120-
true
121-
xs
122-
123-
intToHugeNum
124-
Int
125-
HN.HugeNum
126-
intToHugeNum =
127-
HN.fromNumber
128-
<<< Int.toNumber
129-
130-
derive instance ordEJsonFOrd a Ord (EJsonF a)
131-
instance ord1EJsonFOrd1 EJsonF where
132-
compare1 = compare
133-
13477
instance showEJsonFShow (EJsonF TacitString) where
13578
show = case _ of
13679
Null"Null"
@@ -160,3 +103,41 @@ getType = case _ of
160103
ObjectId _ → JT.ObjectId
161104
Array _ → JT.Array
162105
Map _ → JT.Map
106+
107+
newtype EJsonMap a = EJsonMap (Array (Tuple a a))
108+
109+
derive instance newtypeEJsonMapNewtype (EJsonMap a) _
110+
111+
instance functorEJsonMapFunctor EJsonMap where
112+
map f (EJsonMap xs) = EJsonMap (BF.bimap f f <$> xs)
113+
114+
instance eqEJsonMapEq a Eq (EJsonMap a) where
115+
eq (EJsonMap xs) (EJsonMap ys) =
116+
let
117+
xs' = L.fromFoldable xs
118+
ys' = L.fromFoldable ys
119+
in
120+
isSubobject xs' ys'
121+
&& isSubobject ys' xs'
122+
123+
-- | Very badly performing, but we don't have access to Ord here,
124+
-- | so the performant version is not implementable.
125+
isSubobject a. Eq a L.List (Tuple a a) L.List (Tuple a a) Boolean
126+
isSubobject xs ys = F.foldl (\acc x → acc && F.elem x ys) true xs
127+
128+
instance ordEJsonMapOrd a Ord (EJsonMap a) where
129+
compare (EJsonMap xs) (EJsonMap ys) =
130+
compare (M.fromFoldable xs) (M.fromFoldable ys)
131+
132+
instance showEJsonMapShow (EJsonMap TacitString) where
133+
show (EJsonMap xs) = "(EJsonMap " <> show xs <> ")"
134+
135+
instance foldableEJsonMapF.Foldable EJsonMap where
136+
foldMap f (EJsonMap xs) = F.foldMap (\(Tuple k v) → f k <> f v) xs
137+
foldl f a (EJsonMap xs) = F.foldl (\acc (Tuple k v) → f (f acc k) v) a xs
138+
foldr f a (EJsonMap xs) = F.foldr (\(Tuple k v) acc → f k $ f v acc) a xs
139+
140+
instance traversableEJsonMapT.Traversable EJsonMap where
141+
traverse f (EJsonMap xs) =
142+
EJsonMap <$> T.traverse (\(Tuple k v) → Tuple <$> f k <*> f v) xs
143+
sequence = T.sequenceDefault

src/Data/Json/Extended/Signature/Gen.purs

+2-2
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ import Data.Array as A
1010
import Data.DateTime as DT
1111
import Data.Enum (toEnum)
1212
import Data.HugeNum as HN
13-
import Data.Json.Extended.Signature.Core (EJsonF(..))
13+
import Data.Json.Extended.Signature.Core (EJsonF(..), EJsonMap(..))
1414
import Data.Maybe (fromMaybe)
1515
import Data.Tuple as T
1616

@@ -42,7 +42,7 @@ arbitraryEJsonFWithKeyGen keyGen rec =
4242
Gen.oneOf (pure Null)
4343
[ arbitraryBaseEJsonF
4444
, Array <$> Gen.arrayOf rec
45-
, Map <$> do
45+
, Map <<< EJsonMap <$> do
4646
keys ← distinctArrayOf keyGen
4747
vals ← Gen.vectorOf (A.length keys) rec
4848
pure $ A.zip keys vals

src/Data/Json/Extended/Signature/Json.purs

+3-2
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ import Data.DateTime as DT
1313
import Data.Either as E
1414
import Data.HugeNum as HN
1515
import Data.Int as Int
16-
import Data.Json.Extended.Signature.Core (EJsonF(..))
16+
import Data.Json.Extended.Signature.Core (EJsonF(..), EJsonMap(..))
1717
import Data.Json.Extended.Signature.Parse (parseDate, parseTime, parseTimestamp)
1818
import Data.Json.Extended.Signature.Render (renderDate, renderTime, renderTimestamp)
1919
import Data.Maybe as M
@@ -37,7 +37,7 @@ encodeJsonEJsonF = case _ of
3737
Interval str → JS.jsonSingletonObject "$interval" $ encodeJson str
3838
ObjectId str → JS.jsonSingletonObject "$oid" $ encodeJson str
3939
Array xs → encodeJson xs
40-
Map xsJS.jsonSingletonObject "$obj" $ encodeJson $ asStrMap xs
40+
Map (EJsonMap xs)JS.jsonSingletonObject "$obj" $ encodeJson $ asStrMap xs
4141
where
4242
tuple
4343
T.Tuple JS.Json JS.Json
@@ -89,6 +89,7 @@ decodeJsonEJsonF =
8989
EJsonF JS.Json
9090
strMapObject =
9191
Map
92+
<<< EJsonMap
9293
<<< A.fromFoldable
9394
<<< map (lmap encodeJson)
9495
<<< SM.toList

0 commit comments

Comments
 (0)