这个 do-monad 可以用 let 块代替吗?
Could this do-monad be replaced by a let block?
author here provides 以下示例使用 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]...
commentator here asserts 这是 monad 的一个很好的例子,不仅仅是为了它们本身,而是为了提供真正的增值。
对我来说,这似乎与 let-block 所做的没有什么不同。确实 - Brian Marick here compares the do-monad 到 let 块。
我的问题是:这个do-monad可以用let块代替吗?
在 test.check
的上下文中,答案是 否 ,此 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
在幕后为您做的事情。
尝试将其写成 let
:
(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
returns 一个 generator 不是生成器 的结果。因此,例如 gen/vector
期望 Integer
作为第二个参数而不是 generator
而这个 let
甚至无法编译。
从 test.check 0.9.0
开始,有一个支持此类功能的宏 gen/let
。
author here provides 以下示例使用 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]...
commentator here asserts 这是 monad 的一个很好的例子,不仅仅是为了它们本身,而是为了提供真正的增值。
对我来说,这似乎与 let-block 所做的没有什么不同。确实 - Brian Marick here compares the do-monad 到 let 块。
我的问题是:这个do-monad可以用let块代替吗?
在 test.check
的上下文中,答案是 否 ,此 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
在幕后为您做的事情。
尝试将其写成 let
:
(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
returns 一个 generator 不是生成器 的结果。因此,例如 gen/vector
期望 Integer
作为第二个参数而不是 generator
而这个 let
甚至无法编译。
从 test.check 0.9.0
开始,有一个支持此类功能的宏 gen/let
。