I've got ```kotlin @JsonClass(generateAdapter = tr...
# functional
r
I've got
Copy code
kotlin
@JsonClass(generateAdapter = true)
data class Gallery<T>(val galleryItems: List<GalleryItem<T>>)

@JsonClass(generateAdapter = true, generator = "sealed:type")
sealed interface GalleryItem<T> {
    @TypeLabel("photo")
    @JsonClass(generateAdapter = true)
    data class Photo<T>(val url: T): GalleryItem<T>
    @TypeLabel("video")
    @JsonClass(generateAdapter = true)
    data class Video<T>(val url: T): GalleryItem<T>
}
And
Copy code
val x: Gallery<String>
as well as
Copy code
fun parse(x: String): HttpUrl
and I would like a
Gallery<HttpUrl>
in the end. In Haskell, I'd add a
deriving Functor
to the type declaration and then I could use all the fun combinatorics functions. How would I do that in Kotlin?
s
deriving Functor
๐Ÿ˜… There is nothing like that sadly. Your best is to write a bit of boilerplate IMO.
Copy code
fun <A, B> Gallery<A>.map(transform: (A) -> B)" Gallery<B> = map {
  when(this) {
    is Photo -> Photo(transform(url))
    is Video -> Video(transform(url))
  }
}
That of course doesn't give you all the other goodies from
Functor
& co
r
Apparently I can't have a type-changing
copy
either ๐Ÿ˜ž
s
I'm not sure if you've ever looked into #arrow, but it's a functional library / organisation like many you can find in Scala or other languages. We've been experimenting with things like this for a long time, but we've seen that since Kotlin doesn't support higher kinded types so doing things like ad-hoc polymorphism with typeclasses is not very ergonomic or idiomatic in Kotlin
Aha, but there is a pretty good Optics library !
r
Now we're talking
s
It can generate Optics for data classes and sealed classes out the box for multiplatform projects ๐Ÿ™‚
r
Can I make type-changing lenses? ๐Ÿค”
s
Yes! It supports polymorhic optics, but those cannot be generated out-of-the-box IIRC
Or rather, I'm not sure if the generator support it at the time.
r
Lemme see
Moshi doesn't like my generic sealed classes anyway
Rowtypes when? ๐Ÿ˜„
If you've never worked with them, PureScript has a really cool implementation. They're a godsend working with JSON of any form or sort.
s
I've only toyed with them, but since almost all my work has been constraint to Kotlin for quite some time I've been trying to improve the status quo here ๐Ÿ˜„ I've used this as well when working with cumbersome Json, https://github.com/nomisRev/kotlinx-serialization-jsonpath
r
Neato!
Not too much json work here so far, so all fine.
s
I've been mostly interested on leveraging the Kotlin Coroutine system as an effect system, and being able to reason about effects in a principled way. So you're able to leverage structured concurrency to reason about resource safety for example. https://github.com/arrow-kt/suspendapp#suspendapp-arrows-resource
So trying to flatten all monads, and patterns into
suspend
without losing any guarantees or patterns we are used to from working with
IO
or other monads. This has also eliminated the need for monad transformers, which is quite significant on the JVM which doesn't like a lot of nesting, or capturing lambdas.
r
Reminds me roughly of https://www.fpcomplete.com/blog/2018/10/resourcet-necessary-evil/ but I have no clue if it applies or not, never dug too much into correctness of effect systems
s
It's kind of a necessary evil yes ๐Ÿ˜… Most "complex" systems will interact with other services (resources), and that typically requires connection pools to be efficient. So you're most of the time dealing with some of these concerns. To avoid overuse we typically isolate that usage to where dependency graphs are setup, and with
suspend
we also aim to eliminate the return types in the wrappers. Similar to effect systems so you can do things like.
Copy code
suspend fun ResourceScope.myResource(): A =
  autoCloseable { ConstructResource() }
Some design documents on this for Arrow 2.0: Resource Polymorphic effects