Hi, I'm new to Kotlin and I just started playing w...
# arrow
i
Hi, I'm new to Kotlin and I just started playing with Arrow and I can't understand something. This is an example from the documentation:
Copy code
fun magic(s: String): Either<Exception, String>

val x = magic("2")
val value = when(x) {
    is Either.Left -> when (x.a){
        is NumberFormatException -> "Not a number!"
        is IllegalArgumentException -> "Can't take reciprocal of 0!"
        else -> "Unknown error"
    }
    is Either.Right -> "Got reciprocal: ${x.b}"
}
And above the code, the following is written: You should also notice that we are using SmartCast for accessing 
Left
 and 
Right
 values. I expected that to mean that after matching X with Either.Left, the compiler would know that x is of type Exception (and the same for right, but there that x is of type String). Here you still have to call .a or .b to get the value. So sorry if this is a stupid question, but what exactly is smart casted here and would it be possible to get Kotlin to know that x is of type String after matching it with Right here?
m
Before the
when
, the compiler only knows that
x
is an
Either
. After the
is
in the
when
it now knows that the
x
is more specifically a
Left
or a
Right
. So you don't have to do something like
is Either.Left -> when ((Left) x).a
when you want to use
x
.
t
Either type is not part of the kotlin std and cannot do that kind of smartcasting, with arrow-meta and Union Types you could do it
m
@thanerian Who are you replying to? OP or me?
t
I’m replying to @Ivan Brko, you have explained correctly the current smart cast, and I just pointing that in a future with UnionTypes you could “smartcast” to wrapped values out of the box via arrow-meta
m
Ok, that's what I thought, but wanted to confirm. Thank you.
p
what you're trying is deep pattern matching. I believe
is Either.Left<Throwable>
or similar won't work
try using
fold
instead, it's the same as
when
and it pre-casts the value for you
Copy code
val value = x.fold({ a ->
    when (a){
        is NumberFormatException -> "Not a number!"
        is IllegalArgumentException -> "Can't take reciprocal of 0!"
        else -> "Unknown error"
    }, { b ->
      "Got reciprocal: $b"
    })
i
Thans for the answer, everyone. Fold does seem nicer here so I'll use that.