Malli integration.
Latest stable release is 1.2.0.
deps.edn JAR dependency information:
org.typedclojure/typed.malli {:mvn/version "1.2.0"}
deps.edn Git dependency information:
- Note: use
clj -Sresolve
to resolve the:git/tag
to a:git/sha
org.typedclojure/typed.malli
{:git/url "https://github.com/typedclojure/typedclojure"
:deps/root "typed/malli"
:git/tag "1.2.0"}
Leiningen dependency information:
[org.typedclojure/typed.malli "1.2.0"]
Maven dependency information:
<dependency>
<groupId>org.typedclojure</groupId>
<artifactId>typed.malli</artifactId>
<version>1.2.0</version>
</dependency>
Note: the following assumes you have the Clojure core type annotations and full type checker on your classpath. Here is a quick way to create a REPL to follow this tutorial with:
clj -Sdeps '{:deps {org.typedclojure/typed.malli {:mvn/version "1.2.0"}
;; only needed if omitting typed.clj.checker
org.typedclojure/typed.lib.clojure {:mvn/version "1.2.0"}
org.typedclojure/typed.clj.checker {:mvn/version "1.2.0"}}}'
Now you can execute each form by copying it into this REPL.
(require '[malli.core :as m]
'[typed.malli :as tm]
'[typed.clojure :as t])
typed.malli/validate is a wrapper for malli.core/validate
.
See also:
;; normally, `validate` takes schemas
(m/validate int? "1")
;=> false
(m/validate int? 1)
;=> true
;; the typed variant (note `tm` namespace) takes Typed Clojure types
(tm/validate t/AnyInteger "1")
;=> false
(tm/validate t/AnyInteger 1)
;=> true
;; it can be used to coerce values in a way the type checker understands
(t/cf (fn [x]
{:pre [(tm/validate t/AnyInteger x)]}
(inc x))
[t/Any :-> Number])
;=> [[t/Any -> Number] {:then tt, :else ff}]
;; tm/explain works oppositely
(t/cf (fn [x]
{:pre [(not (tm/explain t/AnyInteger x))]}
(inc x))
[t/Any :-> Number])
;=> [[t/Any -> Number] {:then tt, :else ff}]
typed.malli/parse is a wrapper for malli.core/parse
.
See also:
;; normally, `parse` takes schemas
(m/parse [:orn
[:int int?]
[:bool boolean?]]
1)
;=> [:int 1]
;; `tm/parse` takes Typed Clojure types and infers the return value.
;; use `::tm/name` to specify `:orn` tags (bare union currently unsupported).
(t/defalias ParsableIntOrBool
(t/U ^{::tm/name :int} t/AnyInteger
^{::tm/name :bool} t/Bool))
(tm/parse ParsableIntOrBool true)
;=> [:bool true] : (t/U
; (t/HVec [(t/Val :int) t/AnyInteger])
; (t/HVec [(t/Val :bool) t/Bool])
; (t/Val :malli.core/invalid))
;; example using `tm/parse` to type check a function
(t/cf
(t/fn [a :- ParsableIntOrBool] :- t/AnyInteger
(let [prs (tm/parse ParsableIntOrBool a)]
(assert (not= ::m/invalid prs))
(case (first prs)
:int (second prs)))))
;=> [[ParsableIntOrBool -> t/AnyInteger] {:then tt, :else ff}]
Copyright © Ambrose Bonnaire-Sergeant, Rich Hickey & contributors.
Licensed under the EPL (see the file epl-v10.html).