蒙蒂·霍尔(Monty Hall)和惰性序列(?)

Sol*_*Sol 1 statistics functional-programming clojure

我刚刚开始学习Clojure,并且尝试模拟Monty Hall问题:

(defn create-contest
  "Creates a monty hall doors contest"
  [n]
  (do (def door-with-car (rand-int n))
      (map
       (fn [i] (if (= i door-with-car) :car :closed))
       (range n)))) 

(defn create-doors
  "Create a collection of monty hall contests"
  [doors contests]
  (doall
   (map
     (fn [i] (create-contest i))
     (repeat contests doors))))
Run Code Online (Sandbox Code Playgroud)

但是,每次执行该create-doors功能时,所有带有轿厢的门都位于同一位置:

broker.core> (create-doors 4 10)
((:car :closed :closed :closed)
 (:car :closed :closed :closed)
 (:car :closed :closed :closed)
 (:car :closed :closed :closed)
 (:car :closed :closed :closed)
 (:car :closed :closed :closed)
 (:car :closed :closed :closed)
 (:car :closed :closed :closed)
 (:car :closed :closed :closed)
 (:car :closed :closed :closed))
broker.core> (create-doors 4 10)
((:closed :car :closed :closed)
 (:closed :car :closed :closed)
 (:closed :car :closed :closed)
 (:closed :car :closed :closed)
 (:closed :car :closed :closed)
 (:closed :car :closed :closed)
 (:closed :car :closed :closed)
 (:closed :car :closed :closed)
 (:closed :car :closed :closed)
 (:closed :car :closed :closed))
broker.core> (create-doors 4 10)
((:closed :car :closed :closed)
 (:closed :car :closed :closed)
 (:closed :car :closed :closed)
 (:closed :car :closed :closed)
 (:closed :car :closed :closed)
 (:closed :car :closed :closed)
 (:closed :car :closed :closed)
 (:closed :car :closed :closed)
 (:closed :car :closed :closed)
 (:closed :car :closed :closed))
Run Code Online (Sandbox Code Playgroud)

我究竟做错了什么?

Tay*_*ood 6

您非常接近,您应该只使用一种let表格而不是def这里:

(defn create-contest
  "Creates a monty hall doors contest"
  [n]
  (let [door-with-car (rand-int n)] ;; let instead of def
    (map
      (fn [i] (if (= i door-with-car) :car :closed))
      (range n))))
Run Code Online (Sandbox Code Playgroud)

def会在当前名称空间中将一些值绑定到var,但是您想在此函数的范围内绑定一个值,这let就是好的。有关其他说明,请参见此问答

(defn create-doors
  "Create a collection of monty hall contests"
  [doors contests]
  (map
    create-contest ;; no need to wrap create-contest in another function here
    (repeat contests doors)))
Run Code Online (Sandbox Code Playgroud)

您无需包装create-contest其他函数即可使用map-您只需将函数直接map作为值传递即可。该doall只需要力实现了从懒惰序列的map,所以你可能并不需要/想那里面,create-doors

(create-doors 4 10)
=>
((:closed :closed :car :closed)
 (:closed :closed :closed :car)
 (:closed :car :closed :closed)
 (:closed :closed :closed :car)
 (:closed :car :closed :closed)
 (:closed :car :closed :closed)
 (:closed :car :closed :closed)
 (:closed :closed :closed :car)
 (:closed :closed :car :closed)
 (:closed :closed :car :closed))
Run Code Online (Sandbox Code Playgroud)