This might be a bit noobish of me however I'm some...
# arrow
k
This might be a bit noobish of me however I'm somewhat new to Kotlin. Why can I curry a lambda (or anonymous function) but not a named function? eg:
Copy code
fun add(a: Int, b: Int): Int = a + b
val multiply: (Int, Int) -> Int = { a: Int, b: Int -> a * b }

val add3 = add.curried()(3) // does not compile
val multiply2 = multiply.curried()(2)
Where this affects me is that I want to have a function that can take different parameter types eg: an Int or a String. Standard function overloading gets me out of this
Copy code
fun add(a: Int, b: Int): Int = a + b
fun add(a: String, b: String): Int = add(Integer.parseInt(a), Integer.parseInt(b))
However I lose the nice FP'ness ie: currying, composability, etc.
m
In Kotlin you can't reference the
multiply
function by just stating
multiply
, you have to use the function reference syntax
::multiply
. Does that work for you?
See "Instantiating a function type > Using a callable reference" here: https://kotlinlang.org/docs/lambdas.html#instantiating-a-function-type
k
::add
worked. So simple. Thanks @Mitchell Skaggs
Does the Arrow community prefer to use functions or lambda expressions as a rule?
🤷 1
r
I don’t think there is a general preference for this, both have drawbacks in terms of generics and it depends on how complex the shape is. Callable references for example don’t let you ascribe type arguments and unless the input type is a valid subtype of the lambda type you are stuck using a regular lambda expression:
Copy code
fun <A> foo(a: A) = {}
val f: (Int) -> Unit = ::foo<Int>
//Type inference failed: Not enough information to infer parameter A in fun <A> foo(): () -> Unit
//Please specify it explicitly. Type arguments are not allowed. 
val f2: (Int) -> Unit = { n: Int -> foo(n) } //ok