0

I'm trying to get familiar with the arrow-kt library, but I'm to dumb to get the easiest thing done: Using one of the built in type classes, namely 'Show' I tried it with kapt using the @extension annotation and kapt itself is generating the necessary code as expected, but the reference to the extension function 'show(): String' is missing. Could somebody please help me with this problem? I wasted two days getting this to work.

Thank you very much!

Best regards

Alex

The class to be extended:

package org.hudelundpfusch.sqwakkel.arrowtest

import arrow.extension
import arrow.typeclasses.Show

class Fump(private val fumpel: String) {

    companion object {}

    override fun toString(): String {
        return "Fump(fumpel='$fumpel')"
    }

}

@extension
interface FumpShow
    : Show<Fump> {
    override fun Fump.show(): String = toString()
}

Here I wanted to use the extension function:

package org.hudelundpfusch.sqwakkel.arrowtest

class Gump {

    private val fump: Fump = Fump("Fumpel!")

    fun gumpel(): String = fump.show()

}

But the reference to 'fump.show()' is missing =(

2 Answers2

3

You're missing show.run { }. For extension functions defined in interfaces to work you need to be on their scope, using run or making a class where you're using it extend it. Either

class Gump: FumpShow

or

Fump.show().run { fump.show() }

should give you the results that you want.

Another option would be importing the show function Arrow Meta's processor would create for you using @extension. Make sure to have it properly configured in your build.gradle

kapt "io.arrow-kt:arrow-meta:$arrow_version"

and then it should be as easy as importing show from IntelliJ's suggestions.

El Paco
  • 546
  • 2
  • 6
  • I've replied on Gitter too. I was out of the house yesterday :) – El Paco Jul 22 '19 at 21:59
  • I'm back to your solution... =D But still: I would've expected something more like `fump.show()` or maybe `Fump.show.apply { fump }`. So it looks a little bit complicated and I can't see the benefits right now, because you can pass any String to `Fump.show().run(...)` – Alexander Schell Jul 23 '19 at 04:26
  • I've explained the benefits on gitter. In any case the import solution that I've edited in is better. – El Paco Jul 23 '19 at 14:39
  • Check https://www.pacoworks.com/2018/02/25/simple-dependency-injection-in-kotlin-part-1/ for a longer explanation – El Paco Jul 23 '19 at 14:39
  • Thank you! I'll give it a try. :) – Alexander Schell Jul 23 '19 at 16:03
0

Thank you very much, El Paco!

But I've to admit that this is a bit counterintuitive for me... =/

I now ended up with this approach:

package org.hudelundpfusch.sqwakkel.arrowtest

import org.hudelundpfusch.sqwakkel.arrowtest.fump.show.show

object FumpShowInstance : FumpShow

class Gump {

    private val fump: Fump = Fump("Fumpel!")

    fun gumpel(): String = FumpShowInstance.run { fump.show() }

}

fun main(args: Array<String>) {
    val gump: Gump = Gump();
    println("${gump.gumpel()}")
}

Best regards

Alex