Skip to content

Instantly share code, notes, and snippets.

@timyates
Last active March 7, 2020 07:11
Show Gist options
  • Star 37 You must be signed in to star a gist
  • Fork 6 You must be signed in to fork a gist
  • Save timyates/7674005 to your computer and use it in GitHub Desktop.
Save timyates/7674005 to your computer and use it in GitHub Desktop.
Currying and composition in Java 8
package java8tests ;
import java.util.function.BiFunction ;
import java.util.function.Function ;
public class Currying {
public void currying() {
// Create a function that adds 2 integers
BiFunction<Integer,Integer,Integer> adder = ( a, b ) -> a + b ;
// And a function that takes an integer and returns a function
Function<Integer,Function<Integer,Integer>> currier = a -> b -> adder.apply( a, b ) ;
// Call apply 4 to currier (to get a function back)
Function<Integer,Integer> curried = currier.apply( 4 ) ;
// Results
System.out.printf( "Curry : %d\n", curried.apply( 3 ) ) ; // ( 4 + 3 )
}
public void composition() {
// A function that adds 3
Function<Integer,Integer> add3 = (a) -> a + 3 ;
// And a function that multiplies by 2
Function<Integer,Integer> times2 = (a) -> a * 2 ;
// Compose add with times
Function<Integer,Integer> composedA = add3.compose( times2 ) ;
// And compose times with add
Function<Integer,Integer> composedB = times2.compose( add3 ) ;
// Results
System.out.printf( "Times then add: %d\n", composedA.apply( 6 ) ) ; // ( 6 * 2 ) + 3
System.out.printf( "Add then times: %d\n", composedB.apply( 6 ) ) ; // ( 6 + 3 ) * 2
}
public static void main( String[] args ) {
new Currying().currying() ;
new Currying().composition() ;
}
}
package java8tests;
import java.util.function.IntBinaryOperator ;
import java.util.function.IntFunction ;
import java.util.function.IntUnaryOperator ;
public class NativeIntCurrying {
public void currying() {
// Create a function that adds 2 ints
IntBinaryOperator adder = ( a, b ) -> a + b ;
// And a function that takes an integer and returns a function
IntFunction<IntUnaryOperator> currier = a -> b -> adder.applyAsInt( a, b ) ;
// Call apply 4 to currier (to get a function back)
IntUnaryOperator curried = currier.apply( 4 ) ;
// Results
System.out.printf( "int curry : %d\n", curried.applyAsInt( 3 ) ) ; // ( 4 + 3 )
}
public void composition() {
// A function that adds 3
IntUnaryOperator add3 = (a) -> a + 3 ;
// And a function that multiplies by 2
IntUnaryOperator times2 = (a) -> a * 2 ;
// Compose add with times
IntUnaryOperator composedA = add3.compose( times2 ) ;
// And compose times with add
IntUnaryOperator composedB = times2.compose( add3 ) ;
// Results
System.out.printf( "int times then add: %d\n", composedA.applyAsInt( 6 ) ) ; // ( 6 * 2 ) + 3
System.out.printf( "int add then times: %d\n", composedB.applyAsInt( 6 ) ) ; // ( 6 + 3 ) * 2
}
public static void main( String[] args ) {
new NativeIntCurrying().currying() ;
new NativeIntCurrying().composition() ;
}
}
@Jpaagt
Copy link

Jpaagt commented Sep 28, 2017

jshell experiments based on the above:

jshell> java.util.function.BiFunction<Integer, Integer, Integer> add = (x,y)->x+y;
add ==> $Lambda$14/1529306539@61832929

jshell> Function<Integer, Function<Integer, Integer>> currier = x -> y -> add.apply(x,y);
currier ==> $Lambda$15/1582797472@26653222

jshell> Function<Integer, Integer> addOne = currier.apply(1);
addOne ==> $Lambda$16/1757676444@ae45eb6

jshell> addOne.apply(10)
$5 ==> 11

jshell> java.util.List.of(12,43,56,78,90,98).stream().map(addOne).collect(Collectors.toList());
$6 ==> [13, 44, 57, 79, 91, 99]

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment