Clojure 这个单子可以被let块代替吗?

Clojure 这个单子可以被let块代替吗?,clojure,monads,let,Clojure,Monads,Let,下面的示例演示了如何使用do monad组合测试生成器: (require '[clojure.test.check.generators :as gen]) (require '[clojure.algo.monads :as m]) (m/defmonad gen-m [m-bind gen/bind m-result gen/return]) (def vector-and-elem (m/domonad gen-m [n (gen/choose 1 10)

下面的示例演示了如何使用do monad组合测试生成器:

(require '[clojure.test.check.generators :as gen])
(require '[clojure.algo.monads :as m])
(m/defmonad gen-m 
  [m-bind gen/bind 
   m-result gen/return])

(def vector-and-elem
  (m/domonad gen-m
    [n (gen/choose 1 10)
     v (gen/vector gen/int n)
     e (gen/element v)]
    [v, e]))

(gen/sample vector-and-elem)
    ([[0 -1 1 0 -1 0 -1 1] 0] 
    [[1 1 3 3 3 -1 0 -2 2] 3]
    [[8 4] 8]...
这是单子的一个很好的例子,不仅仅是为了它们自己,而且是为了提供真正的附加值

对我来说,这似乎与let block所做的没有什么不同。的确-将monad转换为let块


我的问题是:这个do monad可以被let块替换吗?
测试的上下文中。检查
答案是,这个
do monad
不能被
let
块替换。但是您可以像这样手动使用
gen/bind
gen/return

(def vector-and-elem
  (gen/bind (gen/choose 1 10)
            (fn [n]
              (gen/bind (gen/vector gen/int n)
                        (fn [v]
                          (gen/bind (gen/elements v)
                                    (fn [e]
                                      (gen/return [v e]))))))))
这就是
Monad
在封面下为您所做的事情

尝试将此作为
编写,让
执行以下操作:

(def vector-and-elem-let
  (let [n (gen/choose 1 10)
        v (gen/vector gen/int n)
        e (gen/elements v)]
    [v e]))

由于函数:
choose
vector
elements
返回的是生成器,而不是生成器的结果,因此不起作用。因此,例如
gen/vector
期望一个
Integer
作为第二个参数,而不是
生成器
,而这个
let
甚至不编译。

从测试开始。检查
0.9.0
有一个宏
gen/let
支持这类事情。

该函数称为not code>元素