You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Clojure/Spec:是否有内置方式将无参函数转为生成器?

Clojure/Spec 无参函数转生成器问题

场景描述

已有一个生成特定类型X实例的无参函数:

(defn generate-sample-of-x [] ... )

希望在Clojure/Spec中将其用作生成器,但未找到内置实现,于是自行编写了辅助函数:

(defn- generator-from-fn "Create a spec generator from a no-arg function"
  [f] (gen/fmap (fn [_] (f)) (gen/return 0)))

该函数可将任意无参函数转为生成器,示例用法:

(generator-from-fn generate-sample-of-x)

用户疑问

  • 是否存在未发现的内置实现?
  • 若没有,是否有更简洁的方式定义该辅助函数?

解答

1. 内置实现情况

Clojure Spec配套的clojure.test.check.generators库中没有专门的内置函数直接将无参函数转为生成器,但可以通过现有API组合实现。

2. 更简洁的实现方式

有几种更简洁的写法,推荐优先使用语义最匹配的方案:

  • 方案一:使用gen/invoke(推荐)
    gen/invoke的设计目的就是在生成器中调用函数,对于无参函数,直接传入函数本身即可。每次生成器生成值时,都会调用该函数获取新的实例,完全符合需求:
(defn- generator-from-fn [f]
  (gen/invoke f))
  • 方案二:简化原有的fmap写法
    如果偏好原有的fmap思路,可以通过替换部分代码让结构更简洁:
    ;; 用constantly替代匿名函数
    (defn- generator-from-fn [f]
      (gen/fmap (constantly (f)) (gen/return 0)))
    
    ;; 用gen/void替代gen/return 0(gen/void是生成nil的轻量生成器)
    (defn- generator-from-fn [f]
      (gen/fmap (fn [_] (f)) gen/void))
    

内容的提问来源于stack exchange,提问作者Mick

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.21 21:30:53