企业🤖AI智能体构建引擎,智能编排和调试,一键部署,支持私有化部署方案 广告
## 柯里化和部分求值 [柯里化](https://en.wikipedia.org/wiki/Currying)(Currying)的名称来自于其发明者之一 *Haskell Curry*。他可能是计算机领域唯一姓氏和名字都命名过重要概念的人(另外就是 Haskell 编程语言)。 柯里化意为:将一个多参数的函数,转换为一系列单参数函数。 ```java // functional/CurryingAndPartials.java import java.util.function.*; public class CurryingAndPartials { // 未柯里化: static String uncurried(String a, String b) { return a + b; } public static void main(String[] args) { // 柯里化的函数: Function<String, Function<String, String>> sum = a -> b -> a + b; // [1] System.out.println(uncurried("Hi ", "Ho")); Function<String, String> hi = sum.apply("Hi "); // [2] System.out.println(hi.apply("Ho")); // 部分应用: Function<String, String> sumHi = sum.apply("Hup "); System.out.println(sumHi.apply("Ho")); System.out.println(sumHi.apply("Hey")); } } ``` 输出结果: ``` Hi Ho Hi Ho Hup Ho Hup Hey ``` **[1]** 这一连串的箭头很巧妙。*注意*,在函数接口声明中,第二个参数是另一个函数。 **[2]** 柯里化的目的是能够通过提供一个参数来创建一个新函数,所以现在有了一个“带参函数”和剩下的 “自由函数”(free argumnet) 。实际上,你从一个双参数函数开始,最后得到一个单参数函数。 我们可以通过添加级别来柯里化一个三参数函数: ```java // functional/Curry3Args.java import java.util.function.*; public class Curry3Args { public static void main(String[] args) { Function<String, Function<String, Function<String, String>>> sum = a -> b -> c -> a + b + c; Function<String, Function<String, String>> hi = sum.apply("Hi "); Function<String, String> ho = hi.apply("Ho "); System.out.println(ho.apply("Hup")); } } ``` 输出结果: ``` Hi Ho Hup ``` 对于每个级别的箭头级联(Arrow-cascading),你都要在类型声明中包裹另一层 **Function**。 处理基本类型和装箱时,请使用适当的函数式接口: ```java // functional/CurriedIntAdd.java import java.util.function.*; public class CurriedIntAdd { public static void main(String[] args) { IntFunction<IntUnaryOperator> curriedIntAdd = a -> b -> a + b; IntUnaryOperator add4 = curriedIntAdd.apply(4); System.out.println(add4.applyAsInt(5)); } } ``` 输出结果: ``` 9 ``` 可以在互联网上找到更多的柯里化示例。通常它们是用 Java 之外的语言实现的,但如果理解了柯里化的基本概念,你可以很轻松地用 Java 实现它们。