Is there any function like ap2, ap3 in arrow-kt? - kotlin

I saw scala code using cats in this post.
val a = Some(7)
val b = Some(9)
Applicative[Option].ap2(Some(add))(a,b)
And I tried migrating this code to kotlin and arrow like following.
Option.applicative()
.tupled(Some(7), Some(9))
.ap(Some(::add))
// works but dirty
fun add(tuple: Tuple2<Int, Int>): Int = tuple.a + tuple.b
// not work, compilation error
// fun add(a: Int, b: Int): Int = a + b
As you noticed, Tuple2 must be specified in the add function signature.
I searched the official document of arrow, but there is no apN function like ap2, ap3, ap4.
Is there any way to use the second function which not included Tuple2 type?

Once version 0.10 is available Arrow will have a .tupled() method on function types that handles this, so you will be able to write:
Option.applicative()
.tupled(Some(7), Some(9))
.ap(::add.tupled())
fun add(a: Int, b: Int) = a + b
for functions of up to 22 arguments.

Related

Kotlin - print function expressions

In C# I can represent a function expression like so
Expression<Func<int, int, int>> add = (a, b) => a + b;
The string representation of the function expression looks like this
(a, b) => (a + b)
In Kotlin I can represent a function expression like so
val add = { a: Int, b: Int -> a + b }
The string representation of the function expression looks like this
(kotlin.Int, kotlin.Int) -> kotlin.Int
Is there a way that Kotlin can represent the function expression more aligned to C#, showing the input parameters and the function body?
val add = { a: Int, b: Int -> a + b }
is equivalent to
Func<int, int, int> add = (a, b) => a + b;
not to Expression<...>. And if you print that, you'll see something like System.Func<int, int, int>, like in Kotlin.
I don't think Kotlin has a type like Expression in the standard library, or that you can implement it without language support. Its reflection API is richer than Java's (see KFunction) but doesn't let you access the body. You could do it with byte code manipulation libraries, but it would be a lot of work.

Curry functions - How to call 3 (or multiple) functions?

I am trying to curry a function in kotlin such that i can call it like this
myAdditionFunction(1)(2)(3)
this call would return 6 because 1+ 2 + 3 = 6
i just need it to perform an addition over all the numbers. actually i really want it to do a builder
pattern in the future but still trying to see how curry functions work. Here is what i have so far:
fun myAdditionFunction(x: Int) { { y: Int -> x + y }
this works for two parameters. so myAdditionFunction(1)(2) will print 3.
i want it to work for 3 or multiple : here is what i have tried for 3 paramters:
fun myAdditionFunction(x: Int) {
var sum = 0
return { y: Int ->
sum = x + y
sum }
}
How do i carry the sum forward and how to make it take a third inner function ?? it wont compile.
but it will not compile
I'm not exactly sure what's going on in either of your examples, and neither compiled on my machine (Kotlin 1.3.10).
However, you can do lambda expressions, as they allow arbitrarily deep nesting. So for 2 variables, you could have
val myAdditionFunction = {x: Int -> {y: Int -> x + y}}
And for three variables, you can go a level deeper:
val myAdditionFunction = {x: Int -> {y: Int -> {z: Int -> x + y + z}}}
Just for reference, a lambda expression (aka anonymous function) is in the form:
val functionName = {argument1: type -> return_value}
I think something can't be an Int and a function simultaneously. Maybe use an extention function on Int class?
operator fun Int.invoke(x: Int) = this + x
val a = 1(2)(3)
With Lionel Briand's great idea to create an operator extension function invoke on Int, you just need another function curry as entry point
operator fun Int.invoke(x: Int) = this + x
fun curry(x: Int) = x
and you can do exactlty what you wanted:
curry(1)(2)(3)(4) // will return 10

How to create String with certain length and same value effectively in Kotlin

I knew this can be achieved with for loop but I am looking for better solution.
createDummyString(1,'A') = 'A'
createDummyString(2.'A') = 'AA'
This will be used in hangman. Thank you.
You can do it like in the example below. To learn more about Strings read this: https://kotlinlang.org/api/latest/jvm/stdlib/kotlin/-string/index.html
fun createDummyString(repeat : Int, alpha : Char) = alpha.toString().repeat(repeat)
Addendum:
If you want to make it more kotlinesque, you can also define repeat as extension function on Char
fun Char.repeat(count: Int): String = this.toString().repeat(count)
and call it like this:
'A'.repeat(1)
CharSequence has an extension method for this.
fun CharSequence.repeat(n: Int): String // for any whole number
Example
println("A".repeat(4)) // AAAA
println("A".repeat(0)) // nothing
println("A".repeat(-1)) // Exception
Reference : https://kotlinlang.org/api/latest/jvm/stdlib/kotlin.text/repeat.html
I created a utility function using infix operator for this :
infix fun Int.times(s : CharSequence): CharSequence{
return s.repeat(this)
}
//Use like val twoAs = 2 times "A"
println(a) // AA

Custom 'typesafe' Int Types

What I would like to have is two different integer types which are semantically distinguishable.
E.g. in this code a 'Meter' type and a 'Pixel' int type
typealias Meter = Int
typealias Pixel = Int
fun Meter.toPixel() = this * 100
fun Pixel.toMeter() = this / 100
fun calcSquareMeters(width: Meter, height: Meter) = width * height
fun calcSquarePixels(width: Pixel, height: Pixel) = width * height
fun main(args: Array<String>) {
val pixelWidth: Pixel = 50
val pixelHeight: Pixel = 50
val meterWidth: Meter = 50
val meterHeight: Meter = 50
calcSquareMeters(pixelWidth, pixelHeight) // (a) this should not work
pixelWidth.toPixel() // (b) this should not work
}
The problem with this solution is
(a) that I can call calcSquareMeters with my 'Pixel' type which I don't want to be possible and
(b) that I can call the toPixel() extension function which I only want to have for my 'Meter' type on my 'Pixel' type which I don't want to be possible.
I guess this is the intended behaviour of typealias, so I guess to achieve my goal I have to use something different than typealias...
So how can I achieve this?
In addition to the existing answer: If you have a lot of common functionality between the two types and don't want to duplicate it, you can work with an interface:
interface MetricType<T> {
val value: Int
fun new(value: Int): T
}
data class Meter(override val value: Int) : MetricType<Meter> {
override fun new(value: Int) = Meter(value)
}
data class Pixel(override val value: Int) : MetricType<Pixel> {
override fun new(value: Int) = Pixel(value)
}
Like this, you can easily define operations on the base interface, such as addition, subtraction and scaling:
operator fun <T : MetricType<T>> T.plus(rhs: T) = new(this.value + rhs.value)
operator fun <T : MetricType<T>> T.minus(rhs: T) = new(this.value + rhs.value)
operator fun <T : MetricType<T>> T.times(rhs: Int) = new(this.value * rhs)
The combination of interface and generics ensures type safety, so you do not accidentally mix types:
fun test() {
val m = Meter(3)
val p = Pixel(7)
val mm = m + m // OK
val pp = p + p // OK
val mp = m + p // does not compile
}
Keep in mind that this solution comes at a runtime cost due to the virtual functions (compared to rewriting the operators for each type separately). This in addition to the overhead of object creation.
Indeed, typealiases don't guarantee this sort of type safety. You'll have to create wrapper classes around an Int value instead to achieve this - it's a good idea to make these data classes so that equality comparisons work on them:
data class Meter(val value: Int)
data class Pixel(val value: Int)
Creation of instances of these classes can be solved with extension properties:
val Int.px
get() = Pixel(this)
val pixelWidth: Pixel = 50.px
The only problematic thing is that you can no longer directly perform arithmetic operations on Pixel and Meter instances, for example, the conversion functions would now look like this:
fun Meter.toPixel() = this.value * 100
Or the square calculations like this:
fun calcSquareMeters(width: Meter, height: Meter) = width.value * height.value
If you really need direct operator use, you can still define those, but it will be quite tedious:
class Meter(val value: Int) {
operator fun times(that: Meter) = this.value * that.value
}
fun calcSquareMeters(width: Meter, height: Meter) = width * height
There is a proposal (not yet guaranteed to be accepted) to add inline classes for this purpose. I.e.
#InlineOnly inline class Meter(val value: Int)
will really be an Int at runtime.
See https://github.com/zarechenskiy/KEEP/blob/28f7fdbe9ca22db5cfc0faeb8c2647949c9fd61b/proposals/inline-classes.md and https://github.com/Kotlin/KEEP/issues/104.
From kotlin doc:
Type aliases do not introduce new types. They are equivalent to the corresponding underlying types. When you add typealias Predicate and use Predicate in your code, the Kotlin compiler always expand it to (Int) -> Boolean. Thus you can pass a variable of your type whenever a general function type is required and vice versa
This means that there isn't possible check over your typealias, and you are rally declaring your extensions functions as:
fun Int.toPixel() = this * 100
fun Int.toMeter() = this / 100
fun calcSquareMeters(width: Int, height: Int) = width * height
fun calcSquarePixels(width: Int, height: Int) = width * height
I fear the only way to achieve that you want is implementing an extra class for each type.
I would also go with the solution from TheOperator. But I would like to add the inline keyword to the operator functions. By doing so you could avoid a virtual function call when ever you use this operators.
inline operator fun <T : MetricType<T>> T.plus(rhs: T) = new(this.value + rhs.value)
inline operator fun <T : MetricType<T>> T.minus(rhs: T) = new(this.value + rhs.value)
inline operator fun <T : MetricType<T>> T.times(rhs: Int) = new(this.value * rhs)

Function definition: fun vs val

I'm curious about what is the suggested way to define member functions in Kotlin. Consider these two member functions:
class A {
fun f(x: Int) = 42
val g = fun(x: Int) = 42
}
These appear to accomplish the same thing, but I found subtle differences.
The val based definition, for instance, seems to be more flexible in some scenarios. That is, I could not work out a straight forward way to compose f with other functions, but I could with g. To toy around with these definitions, I used the funKTionale library. I found that this does not compile:
val z = g andThen A::f // f is a member function
But if f were defined as a val pointing to the same function, it would compile just fine. To figure out what was going on I asked IntelliJ to explicitly define the type of ::f and g for me, and it gives me this:
val fref: KFunction1<Int, Int> = ::f
val gref: (Int) -> Int = g
So one is of type KFunction1<Int, Int>, the other is of type (Int) -> Int. It's easy to see that both represent functions of type Int -> Int.
What is the difference between these two types, and in which cases does it matter? I noticed that for top-level functions, I can compose them fine using either definition, but in order to make the aforementioned composition compile, I had to write it like so:
val z = g andThen A::f.partially1(this)
i.e. I had to partially apply it to this first.
Since I don't have to go through this hassle when using vals for functions, is there a reason why I should ever define non-Unit member functions using fun? Is there a difference in performance or semantics that I am missing?
Kotlin is all about Java interoperability and defining a function as a val will produce a completely different result in terms of the interoperability. The following Kotlin class:
class A {
fun f(x: Int) = 42
val g = fun(x: Int) = 42
}
is effectively equivalent to:
public class A {
private final Function1<Integer, Integer> gref = new Function1<Integer, Integer>() {
#Override
public Integer invoke(final Integer integer) {
return 42;
}
};
public int f(final int value) {
return 42;
}
public Function1<Integer, Integer> getG() {
return gref;
}
}
As you can see, the main differences are:
fun f is just a usual method, while val g in fact is a higher-order function that returns another function
val g involves creation of a new class which isn't good if you are targeting Android
val g requires unnecessary boxing and unboxing
val g cannot be easily invoked from java: A().g(42) in Kotlin vs new A().getG().invoke(42) in Java
UPDATE:
Regarding the A::f syntax. The compiler will generate an extra Function2<A, Integer, Integer> class for every A::f occurrence, so the following code results in two extra classes with 7 methods each:
val first = A::f
val second = A::f
Kotlin compiler isn't smart enough at the moment to optimize such kind of things. You can vote for the issue here https://youtrack.jetbrains.com/issue/KT-9831. In case you are interested, here is how each class looks in the bytecode: https://gist.github.com/nsk-mironov/fc13f2075bfa05d8a3c3
Here's some code showing how f and g are different when it comes to usage:
fun main(args: Array<String>) {
val a = A()
exe(a.g) // OK
//exe(a.f) // does not compile
exe { a.f(it) } // OK
}
fun exe(p: (Int) -> Int) {
println(p(0))
}
Where f and g are:
fun f(x: Int) = 42
val g = fun(x: Int) = 42
You can see that g is an object that can be used like a lambda, but f cannot. To use f similarly, you have to wrap it in a lambda.