Describing JSON Schema in Dhall

Hi all!

I’d like describing a json schema in Dhall. E.g, instead of the following error prone YAML:

type: object
additionalProperties: false
properties:
  foo: 
    type: string   
  bar: 
    type: int   
required:
  - foo

I could write something like (which would be more “type safe”):

object 
  [ { required = True , name ="foo", schema = string }
  , { required = False, name = "bar", schema = int } 
  ]

I know there are some topics discussing about generating Dhall from JSON Schema (or reverse) but this is not what I want. It seems what I want is way more simple and can live entirely in Dhall code.

Is there any lib for describing a json schema in Dhall?

I don’t know of a library. But this is essentially what I did as part an internal project, though I’ve only added functions to produce the parts of a JSON schema that we need.

e.g. here’s the dhall for producing the type part of a schema:

{-|
Defines the available JSON schema [type keywords](https://json-schema.org/understanding-json-schema/reference/type.html#type).
-}
let JSONSchemaType =
      < array | boolean | integer | null | number | object | string >

let type = { type : Text }

let makeJSONSchema =
      λ(x : JSONSchemaType) →
        merge
          { object = { type = "object" } : type
          , array = { type = "array" } : type
          , string = { type = "string" } : type
          , boolean = { type = "boolean" } : type
          , null = { type = "null" } : type
          , number = { type = "number" } : type
          , integer = { type = "integer" } : type
          }
          x

let example0 =
      assert : makeJSONSchema JSONSchemaType.string ≡ { type = "string" }

in  { Type = JSONSchemaType
    , SchemaType = type
    , array = makeJSONSchema JSONSchemaType.array
    , boolean = makeJSONSchema JSONSchemaType.boolean
    , integer = makeJSONSchema JSONSchemaType.integer
    , null = makeJSONSchema JSONSchemaType.null
    , number = makeJSONSchema JSONSchemaType.number
    , object = makeJSONSchema JSONSchemaType.object
    , string = makeJSONSchema JSONSchemaType.string
    }

Here’s the code for oneOf:

{-|
Defines the JSON schema [oneOf](https://json-schema.org/understanding-json-schema/reference/combining.html#oneof)
object and a function for producing valid one of objects.
-}
let jsonType = ./jsonType.dhall

let OneOf = { oneOf : List jsonType.SchemaType }

in  { SchemaType = OneOf
    , makeJSONSchema = λ(x : List jsonType.SchemaType) → { oneOf = x } : OneOf
    }

And so on for various schema components we needed. A schema can be stitched together from these pieces. I don’t think this approach is ideal, but it works for now.

Thanks for the answer.

How do you deal with array items and object properties? What would be the code for describing:

{  "foo" : { "bar": [1,2,3] } }

Seems like we need some recursive type (feasible, but if I can avoid the pain… :smile: )

Since a JSON schema is itself JSON, you could use Prelude.JSON.Type as the recursive type for building one

Seems like we need some recursive type (feasible, but if I can avoid the pain… :smile: )

I was able to avoid that since the schema we’re describing is relatively simple.

But I did the early stages, I thought we might need such recursion and my thought was the same as @Gabriel439’s suggestion.