Sitemap
ProAndroidDev

The latest posts from Android Professionals and Google Developer Experts.

Follow publication

[Kotlin Pearls 4] It’s an Object… It’s a Function… It’s an Invokable

5 min readMar 9, 2019

--

Press enter or click to view image in full size
Currying the Indian way
class ReceiptText(val template: String): (Int) -> String {  override fun invoke(amount: Int): String =
template.replace("%", amount.toString())
}
typealias FIntToString = (Int) -> String
fun receipt(template: String, amount: Int) = 
template.replace("%", amount.toString())
val text = receipt(readTemplateFromConf(), amount)
val receipt = ReceiptText("Thank you for you donation of $%!")//do something else...val text = receipt(123) // "Thank you for you donation of $123!"
fun receiptText(template: String): (Int) -> String = {
amount
-> template.replace("%", amount.toString())
}
sealed class TemplateString//an object with invoke operator
object ReceiptTextObj : TemplateString() {
operator fun invoke(amount: Int): String =
receiptText("My receipt for $%")(amount)
operator fun invoke(template: String, amount: Int): String =
receiptText(template)(amount)
}
val functions = mutableListOf<(Int) -> String>()functions.add(receiptText("TA %"))
functions.add(ReceiptText("Thank you for $%!"))
functions.add(ReceiptTextObj::invoke)
val receipts = functions.mapIndexed{i, f -> f(i+100) }
//["TA 100", "Thank you for $101!", "My receipt for $102"]
from this:
(String, Int, Double) -> Person
to this:
(String) -> (Int) -> (Double) -> Person
data class Person(val name: String, val age: Int, val weight: Double)val personBuilder: (String) -> (Int) -> (Double) -> Person = 
{ name ->
{
age ->
{
weight ->
Person(name, age, weight)
}
}
}
val frank = personBuilder("Frank")(32)(78.5)
//Person(name=Frank, age=32, weight=78.5)")
val names = listOf("Joe", "Mary", "Bob", "Alice")val people: List<Person> = names
.map { personBuilder(it) } //choose the name
.map { it(nextInt(80)) } //a random age
.map { it(nextDouble(100.0)) } //a random weight
//4 random Person instances
LINENUMBER 12 L0
NEW com/ubertob/invokeOperator/ReceiptText
DUP
LDC "Thank you for you donation of $%!"
INVOKESPECIAL com/ubertob/invokeOperator/ReceiptText.<init> (Ljava/lang/String;)V
ASTORE 1
L1
LINENUMBER 14 L1
ALOAD 1
BIPUSH 123
INVOKEVIRTUAL com/ubertob/invokeOperator/ReceiptText.invoke (I)Ljava/lang/String;
ASTORE 2
L0
LINENUMBER 25 L0
LDC "Thank you for you donation of $%!"
INVOKESTATIC com/ubertob/invokeOperator/InheritingFromFunctionsKt.receiptText (Ljava/lang/String;)Lkotlin/jvm/functions/Function1;
ASTORE 1
L1
LINENUMBER 27 L1
ALOAD 1
BIPUSH 123
INVOKESTATIC java/lang/Integer.valueOf (I)Ljava/lang/Integer;
INVOKEINTERFACE kotlin/jvm/functions/Function1.invoke (Ljava/lang/Object;)Ljava/lang/Object; (itf)
CHECKCAST java/lang/String
ASTORE 2
L0
LINENUMBER 37 L0
GETSTATIC com/ubertob/invokeOperator/ReceiptTextObj.INSTANCE : Lcom/ubertob/invokeOperator/ReceiptTextObj;
BIPUSH 123
INVOKEVIRTUAL com/ubertob/invokeOperator/ReceiptTextObj.invoke (I)Ljava/lang/String;
ASTORE 1
object Console {
operator fun invoke (block: (String) -> String): Nothing {
while (true) {
val l = readLine()
if (!l.isNullOrBlank())
println(block(l))
}
}
}
fun main() {
println ("Write your command!")
Console {
val
parts = it.split(' ')
when (parts[0]) {
"go" -> "going ${parts[1]}"
"eat"
-> "eating ${parts[1]}"
"quit"
-> throw InterruptedException("Program has been terminated by user")
else -> "I don't think so..."
}
}
}

--

--

ProAndroidDev
ProAndroidDev

Published in ProAndroidDev

The latest posts from Android Professionals and Google Developer Experts.

Uberto Barbini
Uberto Barbini

Written by Uberto Barbini

JVM and Kotlin independent consultant. Passionate about Code Quality and Functional Programming. Author, public speaker and OpenSource contributor.

Responses (3)