11module Data.Json.Extended.Signature.Core
22 ( EJsonF (..)
3+ , EJsonMap (..)
34 , getType
45 ) where
56
67import Prelude
78
89import Data.Bifunctor as BF
910import Data.DateTime as DT
10- import Data.Eq (class Eq1 , eq1 )
11+ import Data.Eq (class Eq1 )
1112import Data.Foldable as F
1213import Data.HugeNum as HN
13- import Data.Int as Int
1414import Data.Json.Extended.Type as JT
1515import Data.List as L
1616import Data.Map as M
1717import Data.Monoid (mempty )
18- import Data.Ord (class Ord1 , compare1 )
18+ import Data.Newtype (class Newtype )
19+ import Data.Ord (class Ord1 )
1920import Data.TacitString (TacitString )
2021import Data.Traversable as T
2122import Data.Tuple (Tuple (..))
@@ -33,42 +34,34 @@ data EJsonF a
3334 | Interval String
3435 | ObjectId String
3536 | Array (Array a )
36- | Map (Array (Tuple a a ))
37-
38- instance functorEJsonF ∷ Functor EJsonF where
39- map f x =
40- case x of
41- Null → Null
42- String str → String str
43- Boolean b → Boolean b
44- Integer i → Integer i
45- Decimal a → Decimal a
46- Timestamp ts → Timestamp ts
47- Date d → Date d
48- Time t → Time t
49- Interval i → Interval i
50- ObjectId oid → ObjectId oid
51- Array xs → Array $ f <$> xs
52- Map xs → Map $ BF .bimap f f <$> xs
37+ | Map (EJsonMap a )
38+
39+ derive instance functorEJsonF ∷ Functor EJsonF
40+
41+ derive instance eqEJsonF ∷ Eq a ⇒ Eq (EJsonF a )
42+ instance eq1EJsonF ∷ Eq1 EJsonF where eq1 = eq
43+
44+ derive instance ordEJsonF ∷ Ord a ⇒ Ord (EJsonF a )
45+ instance ord1EJsonF ∷ Ord1 EJsonF where compare1 = compare
5346
5447instance foldableEJsonF ∷ F.Foldable EJsonF where
5548 foldMap f = case _ of
5649 Array xs → F .foldMap f xs
57- Map xs → F .foldMap (\( Tuple k v) → f k <> f v) xs
50+ Map xs → F .foldMap f xs
5851 _ → mempty
5952 foldl f a = case _ of
6053 Array xs → F .foldl f a xs
61- Map xs → F .foldl (\acc ( Tuple k v) → f (f acc k) v) a xs
54+ Map xs → F .foldl f a xs
6255 _ → a
6356 foldr f a = case _ of
6457 Array xs → F .foldr f a xs
65- Map xs → F .foldr (\( Tuple k v) acc → f k $ f v acc) a xs
58+ Map xs → F .foldr f a xs
6659 _ → a
6760
6861instance traversableEJsonF ∷ T.Traversable EJsonF where
6962 traverse f = case _ of
70- Array xs → map Array $ T .traverse f xs
71- 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
7265 Null → pure Null
7366 String str → pure $ String str
7467 Boolean b → pure $ Boolean b
@@ -81,108 +74,6 @@ instance traversableEJsonF ∷ T.Traversable EJsonF where
8174 ObjectId oid → pure $ ObjectId oid
8275 sequence = T .sequenceDefault
8376
84- -- Note: this cannot be derived due to integer/decimal equality and map equality
85- instance eq1EJsonF ∷ Eq1 EJsonF where
86- eq1 Null Null = true
87- eq1 (Boolean b1) (Boolean b2) = b1 == b2
88- eq1 (Integer i) (Integer j) = i == j
89- eq1 (Decimal a) (Decimal b) = a == b
90- eq1 (Integer i) (Decimal b) = intToHugeNum i == b
91- eq1 (Decimal a) (Integer j) = a == intToHugeNum j
92- eq1 (String a) (String b) = a == b
93- eq1 (Timestamp a) (Timestamp b) = a == b
94- eq1 (Date a) (Date b) = a == b
95- eq1 (Time a) (Time b) = a == b
96- eq1 (Interval a) (Interval b) = a == b
97- eq1 (ObjectId a) (ObjectId b) = a == b
98- eq1 (Array xs) (Array ys) = xs == ys
99- eq1 (Map xs) (Map ys) =
100- let
101- xs' = L .fromFoldable xs
102- ys' = L .fromFoldable ys
103- in
104- isSubobject xs' ys'
105- && isSubobject ys' xs'
106- eq1 _ _ = false
107-
108- instance eqEJsonF ∷ Eq a ⇒ Eq (EJsonF a ) where
109- eq = eq1
110-
111- -- | Very badly performing, but we don't have access to Ord here,
112- -- | so the performant version is not implementable.
113- isSubobject
114- ∷ ∀ a b
115- . (Eq a , Eq b )
116- ⇒ L.List (Tuple a b )
117- → L.List (Tuple a b )
118- → Boolean
119- isSubobject xs ys =
120- F .foldl
121- (\acc x → acc && F .elem x ys)
122- true
123- xs
124-
125- intToHugeNum
126- ∷ Int
127- → HN.HugeNum
128- intToHugeNum =
129- HN .fromNumber
130- <<< Int .toNumber
131-
132- instance ordEJsonF ∷ Ord a ⇒ Ord (EJsonF a ) where
133- compare = compare1
134-
135- -- Note: this cannot be derived, due to integer/decimal comparisons and map
136- -- comparisons
137- instance ord1EJsonF ∷ Ord1 EJsonF where
138- compare1 Null Null = EQ
139- compare1 _ Null = GT
140- compare1 Null _ = LT
141-
142- compare1 (Boolean b1) (Boolean b2) = compare b1 b2
143- compare1 _ (Boolean _) = GT
144- compare1 (Boolean _) _ = LT
145-
146- compare1 (Integer i) (Integer j) = compare i j
147- compare1 (Integer i) (Decimal b) = compare (intToHugeNum i) b
148- compare1 (Decimal a) (Integer j) = compare a (intToHugeNum j)
149- compare1 _ (Integer _) = GT
150- compare1 (Integer _) _ = LT
151-
152- compare1 (Decimal a) (Decimal b) = compare a b
153- compare1 _ (Decimal _) = GT
154- compare1 (Decimal _) _ = LT
155-
156- compare1 (String a) (String b) = compare a b
157- compare1 _ (String _) = GT
158- compare1 (String _) _ = LT
159-
160- compare1 (Timestamp a) (Timestamp b) = compare a b
161- compare1 _ (Timestamp _) = GT
162- compare1 (Timestamp _) _ = LT
163-
164- compare1 (Date a) (Date b) = compare a b
165- compare1 _ (Date _) = GT
166- compare1 (Date _) _ = LT
167-
168- compare1 (Time a) (Time b) = compare a b
169- compare1 _ (Time _) = GT
170- compare1 (Time _) _ = LT
171-
172- compare1 (Interval a) (Interval b) = compare a b
173- compare1 _ (Interval _) = GT
174- compare1 (Interval _) _ = LT
175-
176- compare1 (ObjectId a) (ObjectId b) = compare a b
177- compare1 _ (ObjectId _) = GT
178- compare1 (ObjectId _) _ = LT
179-
180- compare1 (Array a) (Array b) = compare a b
181- compare1 _ (Array _) = GT
182- compare1 (Array _) _ = LT
183-
184- compare1 (Map a) (Map b) = compare (M .fromFoldable a) (M .fromFoldable b)
185-
18677instance showEJsonF ∷ Show (EJsonF TacitString ) where
18778 show = case _ of
18879 Null → " Null"
@@ -212,3 +103,41 @@ getType = case _ of
212103 ObjectId _ → JT.ObjectId
213104 Array _ → JT.Array
214105 Map _ → JT.Map
106+
107+ newtype EJsonMap a = EJsonMap (Array (Tuple a a ))
108+
109+ derive instance newtypeEJsonMap ∷ Newtype (EJsonMap a ) _
110+
111+ instance functorEJsonMap ∷ Functor EJsonMap where
112+ map f (EJsonMap xs) = EJsonMap (BF .bimap f f <$> xs)
113+
114+ instance eqEJsonMap ∷ Eq 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 ordEJsonMap ∷ Ord a ⇒ Ord (EJsonMap a ) where
129+ compare (EJsonMap xs) (EJsonMap ys) =
130+ compare (M .fromFoldable xs) (M .fromFoldable ys)
131+
132+ instance showEJsonMap ∷ Show (EJsonMap TacitString ) where
133+ show (EJsonMap xs) = " (EJsonMap " <> show xs <> " )"
134+
135+ instance foldableEJsonMap ∷ F.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 traversableEJsonMap ∷ T.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
0 commit comments