Skip to content

Instantly share code, notes, and snippets.

@f-f
Last active September 9, 2019 17:09
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save f-f/f0a791477c5f0fdd0788072673a1e170 to your computer and use it in GitHub Desktop.
Save f-f/f0a791477c5f0fdd0788072673a1e170 to your computer and use it in GitHub Desktop.
;; deps.edn
{:deps
{dhall-clj {:mvn/version "0.2.0"}}}
;; All the imports we need
(require '[dhall-clj.ast :refer :all])
(require '[dhall-clj.core :refer [input-ast]])
(require '[dhall-clj.typecheck :refer [typecheck]])
;; Here we define the Type we want to conform our data to:
(def my-record-type (input-ast "{ foo : Natural }"))
;; Note: we're parsing a Dhall string in here, but you could also build it out of Clojure data,
;; by manipulating the AST directly:
(def my-record-type (->RecordT {"foo" (->NaturalT)}))
;; See here for all the available AST constructors:
;; https://github.com/f-f/dhall-clj/blob/master/src/dhall_clj/ast.clj
;; Note 2: if you're good at spec (I'm not) it might be easy to write a
;; function that takes a spec and returns a Dhall type..
;; There is currently no facility to convert Clojure to Dhall,
;; because the semantics don't exactly match, but you can write one easily
;; for a specific usecase. We basically match on some Clojure data and return Dhall AST
(defn clj->dhall [data]
(condp #(%1 %2) data
nat-int? (->NaturalLit data)
string? (->TextLit (list data))
map? (->RecordLit (apply merge (map (fn [[k v]] {(name k) (clj->dhall v)}) data)))
;; etc
"missing case"))
(defn validate [data typ]
(let [inferred (typecheck (clj->dhall data) {})]
(= inferred typ)))
(validate {:foo 1} my-record-type)
;; => true
(validate {:foo "a"} my-record-type)
;; => false
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment