【发布时间】:2011-11-04 17:41:44
【问题描述】:
我正在学习 Clojure,作为练习,我想编写类似 unix“comm”命令的东西。
为此,我将每个文件的内容读入一个集合,然后使用差异/交集来显示独占/公共文件。
经过大量的repl-time,我想出了这样的设置创建部分:
(def contents (ref #{}))
(doseq [line (read-lines "/tmp/a.txt")]
(dosync (ref-set contents (conj @contents line))))
(我正在使用鸭流/读取行来对文件的内容进行排序)。
这是我第一次尝试任何类型的函数式编程或 lisp/Clojure。例如,我不明白为什么当我在片场上做一个 conj 时,片场仍然是空的。这使我了解了 refs。
- 是否有更好的 Clojure/函数式方法来执行此操作?通过使用 ref-set,我只是将代码扭曲为非功能性思维方式,还是我的代码遵循了应该如何完成的思路?
- 是否有图书馆已经这样做了?这似乎是一件相对普通的事情,但我找不到类似的事情。
【问题讨论】:
-
Brian Carper 的回答很好。避免使用鸭流。它已被弃用,其大部分功能都折叠到
clojure.core和clojure.java.io。 -
关于您对集合“仍然为空”的评论;听起来您正在期待可变的行为。请记住,在 clojure 中,数据类型是不可变的。建立集合是递归完成的,因此
reduce的使用如 Brian Carper 所示(into在内部使用reduce)。 -
@DaveRay 我不知道鸭流的状态。感谢您的信息。
-
@AlexStoddard 是的,这正是我的错误。阅读关于不变性是一回事,真正理解它完全是另一回事。
标签: clojure