Skip to content

Instantly share code, notes, and snippets.

@JordanMartinez
Created June 4, 2021 20:16
Show Gist options
  • Save JordanMartinez/54cd7a2586d9cba35a2ebfa25f930b42 to your computer and use it in GitHub Desktop.
Save JordanMartinez/54cd7a2586d9cba35a2ebfa25f930b42 to your computer and use it in GitHub Desktop.
Building multiple record codecs with common fields among them
module Main where
import Prelude
import Data.Argonaut as Argonaut
import Data.Codec.Argonaut as CA
import Effect (Effect)
import Effect.Console (log)
import TryPureScript (render, withConsole)
import Data.Symbol (SProxy(..))
import Type.Proxy (Proxy(..))
type C = { c :: Boolean } -- suppose it may contain many props
type A = { a :: Int, c :: Boolean } -- contains all props from C and some additional
type B = { b :: Number, c :: Boolean } -- contains all props from C and some additional
-- specifies a single field
mkCodecC :: forall rest
. CA.JPropCodec (Record rest)
-> CA.JPropCodec (Record (c :: Boolean | rest))
mkCodecC nextCodec =
CA.recordProp (SProxy :: SProxy "c") CA.boolean nextCodec
-- take a common field and define a final codec
codecA :: CA.JsonCodec A
codecA = CA.object "A" $ CA.record
# mkCodecC
# {- field a -} CA.recordProp (Proxy :: Proxy "a") CA.int
{-
The above code is the same as writing
```
CA.recordProp (Proxy :: Proxy "a") CA.int
$ mkCodecC
$ CA.record
```
-}
-- specifies multiple fields at once
mkCodecA :: forall rest
. CA.JPropCodec (Record rest)
-> CA.JPropCodec (Record (c :: Boolean, a :: Int | rest))
mkCodecA =
CA.recordProp (SProxy :: SProxy "c") CA.boolean
<<< CA.recordProp (SProxy :: SProxy "a") CA.int
codecA2 :: CA.JsonCodec A
codecA2 = CA.object "A" $ mkCodecA CA.record
main :: Effect Unit
main =
render =<< withConsole do
log $ Argonaut.stringify $ CA.encode codecA {a: 4, c: true }
log ""
log "Uh oh... looks like the order matters!"
log $ Argonaut.stringify $ CA.encode codecA2 {a: 4, c: true }
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment