这句话在 Clojure 中如何正确?

问题描述 投票:0回答:1

这是我写的一个程序,我不知道为什么这是真的。

user=> (defn isClose [t1] (fn [t2] (and (<= (- t1 t2) 20)) (<= (- t2 t1) 20)))
#'user/isClose
user=> ((isClose 50) 10)
true

这不就变成这样了吗

user=> (and (<= 40 20) (<= -40 20))                                            
false
clojure
1个回答
1
投票

你的括号错了。让我们添加一些换行符:

(defn isClose [t1] 
  (fn [t2] 
    (and (<= (- t1 t2) 20)) 
    (<= (- t2 t1) 20)))

观察函数体有两个表达式,而不是一个:一个带有单个参数的

and
,后面跟着一个不相关的
<=
调用。当一个函数体有多个表达式时,在评估所有早期表达式的副作用然后丢弃它们之后,返回最终表达式。你想写的是

(defn is-close [t1] 
  (fn [t2] 
    (and (<= (- t1 t2) 20)
         (<= (- t2 t1) 20))))

确实如您所料。请注意,我还将函数名称修改为典型的 Clojure 命名约定。当然,这没有语义上的区别。叫它

close?
.

就更典型了

手动平衡括号很棘手:当我阅读你的函数时,它看起来不错。只有在将它扩展到多行,并让一个像样的编辑器自动缩进以便布局与语义匹配之后,问题才变得明显。我建议使用支持 lisp 的编辑器,并为清晰起见插入换行符;你应该会发现缩进很有用。

© www.soinside.com 2019 - 2024. All rights reserved.