- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我有一个关于嵌套剂量循环的问题。在开始函数中,一旦找到答案,我将原子设置为 true,以便 :while 的外循环验证失败。然而,它似乎并没有打破它,并且循环继续进行。这是怎么回事?
我对原子、引用、代理的使用也很困惑(为什么它们的更新函数有不同的名称,而机制几乎相同?)等。在这种情况下可以使用原子作为标志吗?显然我需要一个类似变量的对象来存储状态。
(def pentagonal-list (map (fn [a] (/ (* a (dec (* 3 a))) 2)) (iterate inc 1)))
(def found (atom false))
(defn pentagonal? [a]
(let [y (/ (inc (Math/sqrt (inc (* 24 a)))) 6)
x (mod (* 10 y) 10)]
(if (zero? x)
true
false)))
(defn both-pent? [a b]
(let [sum (+ b a)
diff (- a b)]
(if (and (pentagonal? sum) (pentagonal? diff))
true
false)))
(defn start []
(doseq [x pentagonal-list :while (false? @found)]
(doseq [y pentagonal-list :while (<= y x)]
(if (both-pent? x y)
(do
(reset! found true)
(println (- x y)))))))
最佳答案
即使原子设置为 true
,您的版本也无法停止运行,直到内部 doseq
完成(直到 y > x)。一旦内循环完成,它将终止外循环。当我运行它时它最终会终止。不确定您看到了什么。
您不需要两个 doseq
来执行此操作。一个 doseq
可以同时处理两个 seq。
user> (doseq [x (range 0 2) y (range 3 6)] (prn [x y]))
[0 3]
[0 4]
[0 5]
[1 3]
[1 4]
[1 5]
(对于for
也是如此。)据我所知,除了throw
/catch之外,没有任何机制可以“突破”嵌套doseqs
,但这相当不惯用。不过,您根本不需要原子或 doseq
来实现此目的。
(def answers (filter (fn [[x y]] (both-pent? x y))
(for [x pentagonal-list
y pentagonal-list :while (<= y x)]
[x y])))
您的代码风格非常命令式。 “循环这些列表,然后测试值,然后打印一些内容,然后停止循环。”像这样使用原子进行控制在 Clojure 中并不是很惯用。
一种更实用的方法是采用一个 seq(五边形列表)并将其包装在将其转换为其他 seq 的函数中,直到获得一个能够提供您想要的结果的 seq。首先,我使用 for
将此 seq 的两个副本转换为 y <= x 的一个 seq 对。然后我使用 filter
将该 seq 转换为过滤掉我们不关心的值的序列。
filter
和 for
是惰性的,因此一旦找到第一个
有效值(如果您想要一个),它将停止运行。这将返回您想要的两个数字,然后您可以将它们相减。
(apply - (first answers))
或者您可以进一步将函数包装在另一个 map
中来计算差异。
(def answers2 (map #(apply - %) answers))
(first answers2)
以这种方式进行函数式编程有一些优点。 seq 被缓存(如果你像我在这里一样捕获头部),所以一旦计算出一个值,它就会记住它,从那时起你可以立即访问它。如果不重置原子,您的版本就无法再次运行,然后必须重新计算所有内容。使用我的版本,您可以(获取 5 个答案)
获取前 5 个结果,或者根据需要映射结果以执行其他操作。您可以对其进行 doseq
并打印值。等等等等
我确信还有其他(也许更好)的方法可以在不使用原子的情况下完成此操作。通常应该避免改变引用,除非在 Clojure 中 100% 有必要。
用于更改原子/代理/引用的函数名称不同可能是因为机制不同。 Refs 是同步的,并通过事务进行协调。代理是异步的。原子是同步且不协调的。它们都是“更改引用”,并且可能某种 super 功能或宏可以将它们全部包装在一个名称中,但这会掩盖它们在幕后做着截然不同的事情的事实。充分解释这些差异可能超出了 SO 帖子解释的范围,但是 http://clojure.org充分解释了差异的所有细微差别。
关于clojure - 如何摆脱嵌套的剂量,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2841932/
为什么该语言的名称是“Clojure”? 我用谷歌搜索了一下,在#clojure 中询问。到目前为止,还没有运气。 最佳答案 Rich Hickey(他是 Clojure 的设计者)对此的评论是 wi
我不明白为什么升级后会出现以下编译错误: Compiling addr-verify.core Exception in thread "main" java.lang.NoClassDefFound
我试图将从映射操作返回的(惰性)序列传递给另一个映射操作,以便我可以在第一个序列中查找元素。代码从文本文件(以行/列格式)解析一些足球装置,清理它,然后返回一张 map 。 这是代码: (ns fix
我想过滤一组,例如: (filter-set even? #{1 2 3 4 5}) ; => #{2 4} 如果我使用clojure.core/filter我得到一个不是集合的seq: (filte
(defn hi[](+ 5 6)) (hi) (defn hi[](+ 6 7)) (hi) 你好,我是 clojure 的新手。如上所述,我编写了两个具有相同名称的函数。我们可以在 cloj
我按照这个伪代码递归地将十进制转换为二进制。 findBinary(decimal) if (decimal == 0) binary = 0 else binar
我正在尝试学习 Clojure 并尝试定义这个简单的函数: user=> (defn triple [arg] (* 3 arg)) #'user/triple user=> (triple 1) 3
是->和 ->>宏只是为了使代码更具可读性还是它们还有其他特定功能? 最佳答案 线程优先( -> )和线程最后( ->> )是为了使代码更具可读性。但这已经很重要了! 它允许取消嵌套函数调用(示例取自
我在 http://www.learningclojure.com/2010/11/yet-another-way-to-write-factorial.html 上找到了这个代码,但我不明白 pop
我正在阅读 Programming Clojure 2nd edition,在第 49 页它涵盖了 Clojure 的 for 循环结构,它说它实际上是一个序列理解。 作者建议使用以下代码: (def
Clojure 中有双端队列吗?我的印象是 Clojure 的 PersistentQueue 是单端的(我错了吗?)。我需要能够从队列的任一端删除(即“pop”)和“peek”数据。我所说的双端队列
换句话说,有没有办法在看起来不像 (MACRO arg* ...) 的表单上触发宏扩展? . 举一个假设的例子: (defmacro my-var (do (printf "Using my-va
我很难理解懒惰。 有人能帮我理解为什么我下面的函数不是懒惰的吗 (defn my-red ([f coll] (my-red f (first coll) (rest coll) ))
在 Clojure 核心中决定参数函数顺序的规则是什么(如果有的话)? 类似 map 的函数和 filter期望数据结构作为最后一个 争论。 类似 assoc 的函数和 select-keys期待数据
我在 clojuredocs 上遇到过 completing 函数,但目前没有文档。 你能提供一些例子吗? 最佳答案 completing 用于扩充可能没有具有一元“完成”元数的一元重载的二元归约函数
这个现在支持吗?我能找到的唯一信息是来自维基的示例( https://github.com/clojure/core.match/wiki/Deftype-and-defrecord-matching
我正在关注“Clojure in Action”,对此我感到困惑: (defn with-log [function-to-call log-statement ] (fn [& args
对于下面的代码,箭头是宏还是函数名称中的简单字符? (来自 here) (defn file->map [file] ;; TODO ) 最佳答案 箭头是函数名称的一部分。有一个函数定义,不是
Clojure 的 range函数包含来自 start独家在end (如果提供)。核心库中是否有一个函数可以提供完全包含(开始和结束)的范围? 我发现在某些情况下必须调整最终值的代码 - 例如向下而不
当我尝试从 REPL 运行以下代码时(使用动态记录): (defrecord (symbol "rec2") (vec (map symbol ["f1" "f2"]))) 我收到错误 Compile
我是一名优秀的程序员,十分优秀!