Using KFunction1 and lambda


#1

I’d like to create a list of predicates and I tried the code below:

val predicates = listOf(
  { s: CharSequence -> true },
  "\\w+\\s+\\d+-\\d+[.]\\d{4}[.]\\d[.]\\d{2}[.]\\d{4}.*".toRegex()::matches,
)

It fails because because it is inferred with differents types. Why?

val f1: (CharSequence) -> Boolean = { s: CharSequence -> true }
val f2: KFunction1<CharSequence, Boolean> = "\\w+\\s+\\d+-\\d+[.]\\d{4}[.]\\d[.]\\d{2}[.]\\d{4}.*".toRegex()::matches

IMO it should be consistent


#2

Because, f1 is a Lambda which type is kotlin.Function1, f2 is a Function Reference which type is kotlin.reflect.KFunction1.

KFunction1 has more info than Function1 (e.g., reflection info), it can be converted to Function1 implicitly by compiler.

In the case of you example:

I found the type parameter <T> is inferred to KFunction1<CharSequence, Boolean>. (I think that may be a bug of type inference system)
The type of first argument is Function1<CharSequence, Boolean> which can not convert to KFunction1.
However, what you want is List<(CharSequence) -> Boolean>, so you can explicit specify what the <T> is:

val predicates = listOf<(CharSequence) -> Boolean>(
  { s: CharSequence -> true },
  "\\w+\\s+\\d+-\\d+[.]\\d{4}[.]\\d[.]\\d{2}[.]\\d{4}.*".toRegex()::matches,
)

#3

Yes, it seems like bug in type inference. Please file it on https://youtrack.jetbrains.com/issues/KT.


#4

Done: https://youtrack.jetbrains.com/issue/KT-19579