我一直在尝试在clojure中创建monad,这样我就可以将我的纯代码与我不纯的代码分开了,而且我偶然发现了一些订购的东西。
当使用以下代码作为最小用例时,所需的输出是用于打印"请输入您的姓名:"到屏幕然后取一行输入,然后打印回屏幕。下面的代码是应该能够实现的:
;; IO Monad definitions
(defn io-bind
[mv mf]
(fn []
(let [val (mv)
f (mf val)]
(f))))
;; Monadic functions
(defn io-print
[msg]
(fn []
(print msg)))
(defn io-read-line
[_]
(fn []
(read-line)))
;; Entry point
(defn -main
"I don't do a whole lot ... yet."
[& args]
((-> (io-print "Please enter your name: ")
(io-bind io-read-line)
(io-bind io-print))))
我已经遇到过这样的问题,因为它首先使用(read-line)
轮询来自用户的输入,之后只有 然后会打印"请输入您的姓名:"。
在较大的示例中,它仍将以正确的顺序执行所有可见的IO操作,例如,在这种情况下,它会打印出来"请输入您的姓名:"在打印出你输入的内容之前,它仍然会先请求输入。
然而,最奇怪的部分是我在print
中用println
替换io-print
的瞬间,无论情况如何,它都按照意图执行所有排序。
为什么会发生这种情况?例如,print
是否存在println
懒惰的某种方式?
答案 0 :(得分:3)
您需要在print
之后添加以下内容:
(flush)
println
将隐式刷新输出到屏幕,这就是为什么您看到的行为与print
不同。
有关详细信息,请参阅https://clojuredocs.org/clojure.core/flush,所有详细信息均为also the source code。