对clojure函数进行类型检查的最简单、最短的方法是什么。常规的ann形式很短:
(ann bar [Number -> Number])
(defn bar [b]
(+ 2 (foo b)))
但是我们(用宏或其他什么(能让它看起来更小吗,比如:
(defn bar [b : Number -> Number]
(+ 2 (foo b)))
谢谢你的建议!
我认为垂直模式是最好的。另请参阅此博客文章。
这里有一个例子:
(ns tst.demo.core
(:use tupelo.core tupelo.test)
(:require [schema.core :as s]))
(s/defn add2 :- s/Num ; "superclass" for any number
[a :- s/Int ; must be an integer type
b :- Double] ; Must be a java.lang.Double
(+ a b))
(dotest
(throws? (add2 1 2))
(throws? (add2 1.0 2))
(is= 3.0 (add2 1 2.0)))
我也有一些预定义的";"类型";除了基本的。例如,tupelo.schema/Keymap
是任何具有关键字关键字的映射。Pair
是长度=2等的任何矢量或序列。
更新
还请参阅我的Clojure模板项目。特别地,存在文件test/clj/_bootstrap.clj
的唯一目的是在键入lein test
时启用垂直模式类型检查(默认情况下会禁用这些检查,因此在生产中没有成本(。
严格来说,这是规范检查,而不是静态类型,但你可能想看看Guardrails(Ghostwheel的一个分支,它是未维护的(,它旨在解决静态类型所带来的一些问题:
(>defn ranged-rand
[start end]
[int? int? | #(< start end)
=> int? | #(>= % start) #(< % end)]
(+ start (long (rand (- end start)))))