Could this do-monad be replaced by a let block?

倾然丶 夕夏残阳落幕 提交于 2019-12-10 17:56:33

问题


The author here provides the following example usage of a do-monad to combine test generators:

(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]...

There commentator here asserts that this is a great example of monads not just for their own sake, but for providing a genuine value-add.

To me this doesn't seem that different from what a let-block is doing. Indeed - Brian Marick here compares the do-monad to a let block.

My question is: Could this do-monad be replaced by a let block?


回答1:


In the context of test.check the answer is no, this do-monad can't be replaced by a let block. But you can use the gen/bind and gen/return manually like this:

(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]))))))))

This is what the Monad is doing under the covers for you.

Trying to write this as a let:

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

Doesn't work because the functions: choose, vector, and elements returns a generator not the result of the generator. So for example gen/vector expects a Integer as the second argument not a generator and this let doesn't even compile.




回答2:


As of test.check 0.9.0 there is a macro gen/let that supports this sort of thing.



来源:https://stackoverflow.com/questions/28961373/could-this-do-monad-be-replaced-by-a-let-block

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!