diff --git a/pkl-core/src/test/files/LanguageSnippetTests/input/lambdas/compose.pkl b/pkl-core/src/test/files/LanguageSnippetTests/input/lambdas/compose.pkl new file mode 100644 index 000000000..e34e5af5d --- /dev/null +++ b/pkl-core/src/test/files/LanguageSnippetTests/input/lambdas/compose.pkl @@ -0,0 +1,21 @@ +local addOne = (x) -> x + 1 +local double = (x) -> x * 2 + +res1 = double.compose(addOne).apply(5) + +local toUpper = (s: String) -> s.toUpperCase() +local exclaim = (s: String) -> "\(s)!" + +res2 = exclaim.compose(toUpper).apply("hello") + +local addTwo = (x) -> x + 2 +local triple = (x) -> x * 3 + +res3 = triple.compose(addTwo).compose(double).apply(5) + +local identity = (x) -> x + +res4 = addOne.compose(identity).apply(10) +res5 = identity.compose(addOne).apply(10) + +res6 = double.andThen(addOne).apply(5) diff --git a/pkl-core/src/test/files/LanguageSnippetTests/output/lambdas/compose.pcf b/pkl-core/src/test/files/LanguageSnippetTests/output/lambdas/compose.pcf new file mode 100644 index 000000000..6013a7259 --- /dev/null +++ b/pkl-core/src/test/files/LanguageSnippetTests/output/lambdas/compose.pcf @@ -0,0 +1,6 @@ +res1 = 12 +res2 = "HELLO!" +res3 = 36 +res4 = 11 +res5 = 11 +res6 = 11 diff --git a/stdlib/base.pkl b/stdlib/base.pkl index 5e52f9f12..2fd2f7a70 100644 --- a/stdlib/base.pkl +++ b/stdlib/base.pkl @@ -2205,6 +2205,25 @@ external class Function0 extends Function { external class Function1 extends Function { @AlsoKnownAs { names { "call"; "invoke" } } external function apply(p1: Param1): Result + + /// Composes this function with [other]. + /// Returns a new function that first applies [other], then applies this function to the result. + /// + /// Example: + /// ``` + /// local addOne = (x) -> x + 1 + /// local double = (x) -> x * 2 + /// res = double.compose(addOne).apply(5) // Returns 12 + /// ``` + @Since { version = "0.31.0" } + function compose(other: Function1): Function1 = (arg) -> + this.apply(other.apply(arg)) + + /// Composes [other] function with this. + /// Same as `compose` but the functions are executed in reverse order. + @Since { version = "0.31.0" } + function andThen(other: Function1): Function1 = (arg) -> + other.apply(this.apply(arg)) } /// A function literal with two parameters.