原子,或者;
形式为 (x ?? y) 的表达式,其中x和y也是S表达式。
举个例子,递增一组数据,过滤奇数,然后进行排序,最终取出第一个。如果取不到,返回 :not-found 。
(-> [1 2 3]
(->> (map inc)
(filter odd?)
(sort)
(first))
(or :not-found))
; -> 3
(-> [1 1 3]
(->> (map inc)
(filter odd?)
(sort)
(first))
(or :not-found)
; -> :not-found
当然你也可以写成
(if-let [r (first (sort (filter odd? (map inc [1 1 1]))))]
r
:not-found)
; -> :not-found
其实两者都是S表达式,但是下面的写法更加偏向于语句。从串联起来读来讲,前者明显是由于后者的。这要是放在其他函数式语言上,效果更加显著。比如下面重构if-else控制语句到Optional类型。
Optional<Rule> rule = ruleOf(id);
if(rule.isPresent()) {
return transform(rule.get());
} else {
throw new RuntimeException();
}
public Rule transform(Rule rule){
return Rule.builder()
.withName("No." + rule.getId())
.build();
}
这是典型的语句可以重构到表达式的场景,关键是怎么重构呢?
第一步,调转 if 。
Optional rule = ruleOf(id);
if(!rule.isPresent()) {
throw new RuntimeException();
}
return transform(rule.get());
第二步, Optional.map 函数
... return rule.map(r -> transform(r)).get();
第三步, inline transform 函数
...
rule.map(r -> Rule.builder()
.withName("No." + r.getId())
.build()).get();
第四步, Optional.orElseThrow 函数
...
rule.map(r-> Rule.builder()
.withName("No." + r.getId())
.build())
.orElseThrow(() ->new RuntimeException());
第五步,注 if 释语句中的 throw new RuntimeException()
if(!rule.isPresent()) {
// throw new RuntimeException();
}
这时候发现语句中为空,即可将整个语句删除。可以考虑 inline rule 。
ruleOf(id).map(r-> Rule.builder()
.withName("No." + r.getId())
.build())
.orElseThrow(() ->new RuntimeException());
完毕。
把几个简单的想法合并成一个复合概念,从而创造出所有复杂的概念。
简单的或复杂的两种思想融合在一起,并立即把它们联系起来,不要把它们统一起来,从而得到它所有的关系思想。
把他们与其他所有陪伴他们的真实存在的想法分开:这就是所谓的抽象,因此所有的一般想法都是被提出来的。
推荐:初探函数式编程
[继续向下看廖大教程,看到了函数式编程这一节,当时是觉得没啥用直接跳过了,这次准备要仔细看一遍了,并记录下一些心得。]
本文来自电脑杂谈,转载请注明本文网址:
http://www.pc-fly.com/a/jisuanjixue/article-83096-7.html
quot
错了