微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

我可以使用 Clojure 规范验证函数吗?

如何解决我可以使用 Clojure 规范验证函数吗?

我可以使用 Clojure 规范系统来定义函数签名并验证函数是否满足它们吗?

这里有一些我尝试过但没有成功的例子

(s/valid? (s/fspec :args string? :ret string?) identity) ;; false

(def nope identity)
(s/valid? (s/fspec :args string? :ret string?) nope) ;; false

(s/conform (s/fspec :args string? :ret string?) identity) ;; invalid

(defn strmap [s] {:pre [(s/valid? string? s)] :post [(s/valid? string? %)]} s)
(s/valid? (s/fspec :args string? :ret string?) strmap) ;; false

(s/fdef strmap :args string? :ret string?)
(s/valid? strmap strmap) ;; true

(s/def ::str-pred (s/fspec :args string? :ret boolean?))
(s/valid ::str-pred (fn [s] true)) ;; false

我知道 fdef,但我想要一些我可以创作的东西。例如,创建相关函数签名的映射。

解决方法

您可以使用 :args 访问函数的 :rets/get-spec 规范,然后进行验证:

user=> (require '[clojure.spec.alpha :as s])
nil
user=> (defn strmap [s] s)
#'user/strmap
user=> (s/fdef strmap :args string? :ret string?)
user/strmap
user=> (s/valid? (:args (s/get-spec `strmap)) "foo")
true
user=> (s/valid? (:args (s/get-spec `strmap)) :bar)
false

我在 re-find.web 中使用它。

,

事实证明规范确实处理函数,但它期望参数是一个元组。

id=31

匿名函数文字似乎存在一些问题。我可能对宏扩展有些误解。

(s/valid? (s/fspec :args (s/cat :arg1 string?) :ret string?) identity) ;; true!
(s/valid? (s/fspec :args (s/cat :arg1 string?) :ret string?) (fn [x] (str x "hi there"))) ;; true
(s/valid? (s/fspec :args (s/cat :arg1 string?) :ret string?) (fn [x] x)) ;; true

(s/valid? (s/fspec :args (s/cat :arg1 string?) :ret string?) (fn [x] 42)) ;; false
,

clojure.spec 的替代方案,malli 是一个数据驱动的架构库,它具有 support for function schemas

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其他元素将获得点击?
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。)
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbcDriver发生异常。为什么?
这是用Java进行XML解析的最佳库。
Java的PriorityQueue的内置迭代器不会以任何特定顺序遍历数据结构。为什么?
如何在Java中聆听按键时移动图像。
Java“Program to an interface”。这是什么意思?