柯里化
在理论计算机科学中,柯里化提供了在简单的理论模型中,比如:只接受一个单一参数的lambda演算中,研究带有多个参数的函数的方式。
实际上就是单可变参数的情况下我们进行一次逻辑抽取,这是模块化代码的一个重要思路。
package lambdasinaction.chap14; import java.util.function.DoubleUnaryOperator; public class Currying { public static void main(String[] args) { DoubleUnaryOperator convertCtoF = curriedConverter(9.0/5, 32); DoubleUnaryOperator convertUSDtoGBP = curriedConverter(0.6, 0); DoubleUnaryOperator convertKmtoMi = curriedConverter(0.6214, 0); System.out.println(convertCtoF.applyAsDouble(24)); System.out.println(convertUSDtoGBP.applyAsDouble(100)); System.out.println(convertKmtoMi.applyAsDouble(20)); DoubleUnaryOperator convertFtoC = expandedCurriedConverter(-32, 5.0/9, 0); System.out.println(convertFtoC.applyAsDouble(98.6)); } static double converter(double x, double y, double z) { return x * y + z; } static DoubleUnaryOperator curriedConverter(double y, double z) { return (double x) -> x * y + z; } static DoubleUnaryOperator expandedCurriedConverter(double w, double y, double z) { return (double x) -> (x + w) * y + z; } }
持续数据化,数据透明原则
package lambdasinaction.chap14; import java.util.function.Consumer; public class PersistentTrainJourney { public static void main(String[] args) { TrainJourney tj1 = new TrainJourney(40, new TrainJourney(30, null)); TrainJourney tj2 = new TrainJourney(20, new TrainJourney(50, null)); TrainJourney appended = append(tj1, tj2); visit(appended, tj -> { System.out.print(tj.price + " - "); }); System.out.println(); // A new TrainJourney is created without altering tj1 and tj2. TrainJourney appended2 = append(tj1, tj2); visit(appended2, tj -> { System.out.print(tj.price + " - "); }); System.out.println(); // tj1 is altered but it's still not visible in the results. TrainJourney linked = link(tj1, tj2); visit(linked, tj -> { System.out.print(tj.price + " - "); }); System.out.println(); // ... but here, if this code is uncommented, tj2 will be appended // at the end of the already altered tj1. This will cause a // StackOverflowError from the endless visit() recursive calls on // the tj2 part of the twice altered tj1. /*TrainJourney linked2 = link(tj1, tj2); visit(linked2, tj -> { System.out.print(tj.price + " - "); }); System.out.println();*/ } static class TrainJourney { public int price; public TrainJourney onward; public TrainJourney(int p, TrainJourney t) { price = p; onward = t; } } static TrainJourney link(TrainJourney a, TrainJourney b) { if (a == null) { return b; } TrainJourney t = a; while (t.onward != null) { t = t.onward; } t.onward = b; return a; } static TrainJourney append(TrainJourney a, TrainJourney b) { return a == null ? b : new TrainJourney(a.price, append(a.onward, b)); } static void visit(TrainJourney journey, Consumer<TrainJourney> c) { if (journey != null) { c.accept(journey); visit(journey.onward, c); } } }
两个比较使用的例子