Vitali Plagov
03/29/2022, 12:50 PM// java
var words = List.of("one", "two", "three");
Function<Integer, Predicate<String>> lengthFun = (minLength) -> (str) -> str.length() > minLength;
Predicate<String> isLongerThan2 = lengthFun.apply(2);
Predicate<String> isLongerThan3 = lengthFun.apply(3);
var longerThan2 = words.stream().filter(isLongerThan2).collect(Collectors.toList());
var longerThan3 = words.stream().filter(isLongerThan3).collect(Collectors.toList());
I know that these predicates are pretty straightforward and can be inlined straight into the filter { }
function. But I’m more interested in a general approach of how to do it.hfhbd
03/29/2022, 12:58 PMPredicate
, I would use this, because a Predicate is just a function: (String) -> Boolean:
val words = listOf("one", "two", "three")
val lengthFun = fun String.(minLength: Int): Boolean = length > minLength
val isLongerThan2 = fun String.() = lengthFun(2)
val isLongerThan3 = fun String.() = lengthFun(3)
val longerThan2 = words.filter(isLongerThan2)
val longerThan3 = words.filter(isLongerThan3)
You could also use the lambda expression:
val lengthFun = { str: String, minLength: Int -> str.length > minLength }
val isLongerThan2 = { str: String -> lengthFun(str, 2) }
val isLongerThan3 = { str: String -> lengthFun(str ,3) }
Rob Elliot
03/29/2022, 1:01 PMval words = listOf("one", "two", "three")
val lengthFun: (Int) -> ((String) -> Boolean) = { minLength -> { str -> str.length > minLength } }
val isLongerThan2: (String) -> Boolean = lengthFun(2)
val isLongerThan3: (String) -> Boolean = lengthFun(3)
val longerThan2: List<String> = words.filter(isLongerThan2)
val longerThan3: List<String> = words.filter(isLongerThan3)
fun <A, B, R> ((A, B) -> R).curry(a: A): (B) -> R = { b: B -> this(a, b) }
val words = listOf("one", "two", "three")
val lengthFun: (Int, String) -> Boolean = { minLength, str -> str.length > minLength }
val isLongerThan2: (String) -> Boolean = lengthFun.curry(2)
val isLongerThan3: (String) -> Boolean = lengthFun.curry(3)
val longerThan2: List<String> = words.filter(isLongerThan2)
val longerThan3: List<String> = words.filter(isLongerThan3)
Vitali Plagov
03/29/2022, 1:25 PMString.(minLength: Int)
and String.()
are extension functions of String type?hfhbd
03/29/2022, 1:28 PMVitali Plagov
03/29/2022, 1:39 PMfilter { }
function and just to the filter()
oneRob Elliot
03/29/2022, 1:53 PMxs.filter { x -> ... }
is syntax sugar for xs.filter({ x -> ... })
- you are passing a function literal { x -> ... }
as the argument to filter
, you just don't have to put the argument parentheses around it (in fact it's good style not to ).
So when you call words.filter { isLongerThan2 }
it will not compile, because { isLongerThan2 }
is a function literal for a function of type () -> (String) -> Boolean
, and filter
needs (String) -> Boolean
.
You could use words.filter { isLongerThan2(it) }
- a function literal with a single parameter automatically gets a parameter called it
if you do not provide a parameter list. But that's exactly the same as words.filter(isLongerThan2)
(though perhaps a little simpler to read).val words = listOf("one", "two", "three")
fun String.isLongerThan(minLength: Int): Boolean = length > minLength
val longerThan2 = words.filter { it.isLongerThan(2) }
val longerThan3 = words.filter { it.isLongerThan(3) }
Vitali Plagov
03/29/2022, 1:59 PM