m4g*_*g13 1 functional-programming var clojure
我有这个变量,手,当我自己定义它时工作得很好.
(def yourHand
(map
;;fn
#(let [x %]
(cond
;;hearts
(< x 10) (* x -1)
(< x 13) -10
;;diamonds
(< x 23) (* (mod x 13) -1)
(< x 26) -10
;;clubs
(< x 36) (mod x 13)
(< x 39) 10
;;spades
(< x 49) (mod x 13)
(< x 52) 10
))
;;list
(take (rand-int 12) (repeatedly #(+ 1 (rand-int 52))))))
Run Code Online (Sandbox Code Playgroud)
我想在这个函数中使用这个变量.当我首先定义变量然后在函数中使用它的名称时,这很好用.
(reduce + (vec (map #(let [x %]
(cond
(= x 1) 1
:else 0
))
yourHand)))
Run Code Online (Sandbox Code Playgroud)
当我尝试在函数中定义变量时,问题就出现了,就像这样.
(reduce + (vec (map #(let [x %]
(cond
(= x 1) 1
:else 0
))
(def hand
(map
;;fn
#(let [x %]
(cond
;;hearts
(< x 10) (* x -1)
(< x 13) -10
;;diamonds
(< x 23) (* (mod x 13) -1)
(< x 26) -10
;;clubs
(< x 36) (mod x 13)
(< x 39) 10
;;spades
(< x 49) (mod x 13)
(< x 52) 10
))
;;list
(take (rand-int 12) (repeatedly #(+ 1 (rand-int 52)))))))))
Run Code Online (Sandbox Code Playgroud)
如果不是两件事,这就没有必要了.首先,如果可能的话,我想将这个程序简化为一个函数(我认为/是/可能!).其次,我需要在程序的另一个点使用这个变量,所以我需要能够以某种方式引用它.
无论如何,当我尝试评估上述函数时,它抱怨它不知道"如何从:clojure.lang.Var创建ISeq".(这是错误:IllegalArgumentException不知道如何创建ISeq:clojure.lang.Var clojure.lang.RT.seqFrom(RT.java:542))我假设这意味着它不知道如何使用我的变量作为向量...但是当我在函数外部定义变量时,似乎将它用作矢量就好了!
有什么建议?
Tay*_*ood 10
你不应该尝试def
在函数内部.通常def
s用于顶级命名空间值; 加载命名空间后不会(通常)更改的内容.
让我们重构代码以获得一些不依赖于顶级/静态命名空间值的可重用函数.而不是(def yourHand ...)
我们可以有一个生成手的功能:
(defn deal-hand []
(map
;;fn
#(cond ;; you have a subtle bug here that sometimes returns nil
;;hearts
(< % 10) (* % -1)
(< % 13) -10
;;diamonds
(< % 23) (* (mod % 13) -1)
(< % 26) -10
;;clubs
(< % 36) (mod % 13)
(< % 39) 10
;;spades
(< % 49) (mod % 13)
(< % 52) 10)
;;list
(take (rand-int 12) (repeatedly #(inc (rand-int 52))))))
Run Code Online (Sandbox Code Playgroud)
然后,如果你仍然想要一个命名空间def
,你可以这样得到它:
(def your-hand (deal-hand))
Run Code Online (Sandbox Code Playgroud)
我们可以换你reduce
在另一个函数,需要一个手:
(defn score-hand [hand] ;; I made a few simplifications here, but logic is the same
(reduce + (mapv #(if (= 1 %) 1 0) hand)))
Run Code Online (Sandbox Code Playgroud)
现在你有两个可以生成和得分的可重用函数:
(deal-hand)
=> (-10 -9 -9 -10 -3 7)
(deal-hand)
=> (8 -2 10 -9 1 2 -10 3 nil 5)
(score-hand (deal-hand))
=> 1
Run Code Online (Sandbox Code Playgroud)
如果您需要在程序的其他部分使用手,请考虑如何构建函数以将手作为输入,以及手可以如何在程序的功能中流动.