Closed wclr closed 3 years ago
Ultimately, you'd have to write something like:
mkCodecC :: forall r' r. Cons "c" Boolean r r' => JPropCodec (Record r) -> JPropCodec (Record r')
mkCodecC nextCodec = nextCodec
# recordProp (Proxy :: Proxy "c") CA.boolean
-- if you had more fields then...
-- add more `recordProp`s and add another `Cons`
-- constraint above
-- # recordProp (Proxy :: Proxy "nextField") CA.int
-- # recordProp (Proxy :: Proxy "nextField") CA.string
codec :: JsonCodec A
codecA = record
# mkCodecC
# recordProp (Proxy :: Proxy "a") CA.int
If you look at RowListCodec, which is used in the more "convenient" version of encoding a record, object
, that's how it constructs the record. It's basically doing a fold over the row via RowList where each iteration adds another key and its codec to the final record codec
@JordanMartinez thanks! Though your code seems to show the error inside mkCodecC
, I can not actually figure out what is wrong with it.
Could not match type
( c :: Boolean
| r0
)
with type
r'1
@wclr Thanks! Looks like I was wrong, but I found that this compiles (although order matters still):
https://try.purescript.org/?gist=54cd7a2586d9cba35a2ebfa25f930b42
Yeah, there's a few ways of doing it, but you've discovered the important part - you need to define codecs just for the fields (JPropCodec
) and turn them into an "actual" codec with CA.record
.
It's a bit the codec equivalent of doing something like:
type AProps r = ( a :: Int | r )
type BProps r = ( b :: Number | r )
type CProps r = ( c :: Boolean | r )
type A = Record (AProps + CProps + ())
type B = Record (BProps + CProps + ())
type C = Record (CProps ())
Basically you need to separate the properties (rows) from the records (objects).
If there are types:
What would be the best way to get codecs for
A
andB
, but without defining in each of them codecs for properties fromC
type? Maybe something like merging codecs produced byrecord
(JPropCodec)?