Clojure 蒙蒂·霍尔与懒惰序列(?)

Clojure 蒙蒂·霍尔与懒惰序列(?),clojure,functional-programming,statistics,Clojure,Functional Programming,Statistics,我刚刚开始学习Clojure,我正在尝试模拟这个问题: 但是每次我执行创建门功能时,所有带车的门都会在相同的位置: 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 :clos

我刚刚开始学习Clojure,我正在尝试模拟这个问题:

但是每次我执行
创建门
功能时,所有带车的门都会在相同的位置:

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

我做错了什么?

你很接近,你应该使用
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))))
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)))
您不需要将
创建竞赛
包装到另一个函数中以与
地图
一起使用-您只需将该函数作为值直接传递给
地图
doall
仅用于强制实现来自
map
的惰性序列,因此您可能不需要/不希望在
内创建门

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

您非常接近,您应该在此处使用
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))))
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)))
您不需要将
创建竞赛
包装到另一个函数中以与
地图
一起使用-您只需将该函数作为值直接传递给
地图
doall
仅用于强制实现来自
map
的惰性序列,因此您可能不需要/不希望在
内创建门

(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))
从开始,您可以更简洁地表达这两个函数,尽管我不确定简明版本是否清晰

您的
create contest
map
功能会测试每个数字
i
,以确定它是否是一个。最好直接换一个。要做到这一点,我们需要一个向量,我认为在模拟游戏时,您无论如何都要查找该向量:

 (defn create-contest [n]
  (assoc (vec (repeat n :closed)) (rand-int n) :car))
您的
create doors
函数反复将相同的参数传递给它的
map
函数。您可以在闭包上使用,以获得相同的效果:

(defn create-doors [doors contests]
  (repeatedly contests (partial create-contest doors)))

从开始,您可以更简洁地表达这两个函数,尽管我不确定简明版本是否清晰

您的
create contest
map
功能会测试每个数字
i
,以确定它是否是一个。最好直接换一个。要做到这一点,我们需要一个向量,我认为在模拟游戏时,您无论如何都要查找该向量:

 (defn create-contest [n]
  (assoc (vec (repeat n :closed)) (rand-int n) :car))
您的
create doors
函数反复将相同的参数传递给它的
map
函数。您可以在闭包上使用,以获得相同的效果:

(defn create-doors [doors contests]
  (repeatedly contests (partial create-contest doors)))