https://kotlinlang.org logo
Join Slack
Powered by
# arrow
  • r

    raulraja

    07/17/2025, 5:19 PM
    https://deepwiki.com/arrow-kt/arrow This works surprisingly well to get info about arrow's apis
    arrow intensifies 3
    y
    • 2
    • 2
  • j

    Jonathan

    07/18/2025, 4:50 PM
    Does Arrow libraries support KotlinMultiplatform?
    👌 7
  • j

    Jokubas Alekna

    07/21/2025, 3:46 PM
    Has anyone thought about how Arrow could help with the issue of unchecked exceptions? Even though the design of Arrow is meant for domain errors, in the real world the line gets quite blurry, I have noticed that a lot of projects that use arrow end up catching exceptions and converting them into Eithers, even the "best practices" example from the Arrow docs has this issue: https://github.com/nomisRev/ktor-arrow-example. I really like the idea in ZIO/effect.ts of having the ability to choose how you want to handle those types of IO exceptions. Would safe wrappers for ktor client/server, kotlinx serialization and SQLDelight or sqlc be too unidiomatic for Kotlin?
    p
    y
    • 3
    • 4
  • m

    Michael Friend

    07/24/2025, 5:48 PM
    Is there a clean approach to declaring essentially a union error type for functions to reduce redundancy/wrapping on more generic error types? Basically what i have is some HttpClient helper functions that use a sealed interface
    HttpClientError
    (UnsuccessfullResp, ResponseParse etc) to report more http related generic errors, and i have client classes for various apis that use these functions but want to basically add some more api specific errors like
    FilteringError
    to the signature of those client functions, to make the overall error type of these essentially
    HttpClientError | MyApiSpecificError
    (or maybe even more fine tuned if some end points have possible logic errors that others dont). Solutions Ive used in the past are this quick and dirty method of just doing
    interface HttpClientError: MyApiAError, MyApiBError
    but that obviously gets gross fast, or what i assume is the recommended approach of having
    MyApiError
    have a subclass that wraps any
    HttpClientError
    . Is the latter the most "functional idiomatic" approach or is there something that doesnt require writing code to wrap HttpClient error in every call?
    s
    • 2
    • 5
  • s

    sindrenm

    07/29/2025, 1:08 PM
    For the Optics code-gen plugin, is there a reason for not using something like KotlinPoet today? I found some talk around KotlinPoet here in 2017, wondering if that's been revisited. I think it could make the generated code a little more human-readable by at least using imports instead of fully qualified names all over. https://kotlinlang.slack.com/archives/C5UPMM0A0/p1504594831000271
    s
    a
    • 3
    • 6
  • k

    Kev

    07/30/2025, 7:05 AM
    Does the Arrow IntelliJ plugin highlight when you miss a bind within an either construction?
    a
    y
    h
    • 4
    • 4
  • u

    Ulrich Schuster

    07/31/2025, 10:07 AM
    I often find myself writing code in an
    EitherNel
    context –e.g., resulting from
    zipOrAccumulate
    . But then I need to
    bind
    over a function that returns a simple
    Either
    . This effectively forces me to write lots of boilerplate
    .toEitherNel().bind()
    . Is there a combined helper function avaiilable? Or am I using
    EitherNel
    in a non-idiomatic way?
    a
    • 2
    • 2
  • s

    sindrenm

    08/01/2025, 10:47 AM
    Found a couple of bugs related to optics-ksp, filed them here: • https://github.com/arrow-kt/arrow/issues/3691 • https://github.com/arrow-kt/arrow/issues/3692 They're both related to generics, but the first one is KSP2-related, which begs the question: Is KSP2 officially supported? I would imagine it is, but asking here, just to be sure.
    a
    • 2
    • 2
  • d

    dave08

    08/12/2025, 5:34 AM
    It would have been nice to have links to source code from the arrow api docs... I think at a certain point it was lost when migrating to the new docs.
    s
    a
    • 3
    • 3
  • h

    Huib Donkers

    08/14/2025, 5:18 PM
    I'm wondering about the
    contract
    specified for
    Either::getOrNull
    . It seems incorrect in case
    B
    (right) is nullable. For reference:
    Copy code
    public fun getOrNull(): B? {
        contract {
          returns(null) implies (this@Either is Left<A>)
          returnsNotNull() implies (this@Either is Right<B>)
        }
        return getOrElse { null }
      }
    But maybe I'm misunderstanding something about contracts (or arrow). I'm actually unable to get my examples to work, seems my setup is wacky..
    Copy code
    fun foo(either: Either<String, Int?>) = if (either.isLeft()) "Left(${either.value})" else "Right(${either.value})" // IntelliJ highlights as of this compiles and either is smart cast to Left and Right, but when compiling it gives the error "Unresolved reference: value"
    
    fun bar(either: Either<String, Int?>) = if (either.getOrNull() == null) "Left(${either.value})" else "Right(${either.value})" // IntelliJ highlighting and compiler agree: no smart casting (but what does the contract do then?)
    But regardless of my potentially wacky setup, what should happen when I call
    bar(Either.Right(null))
    ?
    ➕ 1
    y
    d
    • 3
    • 8
  • d

    dave08

    08/17/2025, 7:19 AM
    Intellij's Junie seems to not be aware of all the nice extension functions and methods on Either... to get a Right it tries casting with as? and gets the value... and to wrap into a Right it uses it's constructor, not the .right() function... 😵‍💫. I even tried adding context7 and updating Arrow's docs on it's site... is there any way to get this to work right?
    s
    • 2
    • 5
  • e

    Erik Dreyer

    08/20/2025, 10:19 AM
    Oh! When is this getting released? 🙂 https://github.com/arrow-kt/arrow/pull/3646
    👀 4
    a
    m
    • 3
    • 3
  • c

    Carter Hudson

    08/20/2025, 7:17 PM
    Is setting multiple values with Optics supported out-of-the-box? I saw a thread from 2021 that said it’s not, but that was dealing with sealed classes, and I thought things may have changed in the years since.
    d
    • 2
    • 1
  • e

    Erik Dreyer

    08/24/2025, 3:57 PM
    I’m probably not the first to do this. I wrote an article on how to make invalid domain states unrepresentable using Kotlin/Arrow. Critical feedback encouraged: Article: https://dev.to/edreyer/making-illegal-states-unrepresentable-in-kotlin-2k6l corresponding repo: https://github.com/edreyer/safe-domain
    y
    f
    m
    • 4
    • 5
  • d

    Dirk

    09/01/2025, 8:49 AM
    Hi, I'm running into an issue with generated lenses. I have UUID fields in my classes which unfortunately require an
    @OptIn
    annotation. The problem is that this annotation isn't being carried over to the files generated by KSP. How can I configure my project to set this opt-in globally? I've already tried the following in the build.gradle.kts:
    Copy code
    kotlin {
        js(IR) {...}
        jvm {}
    
        compilerOptions {
            freeCompilerArgs.addAll(
                "-Xcontext-parameters",
                "-opt-in=kotlin.uuid.ExperimentalUuidApi"
            )
        }
    
        sourceSets {
            all {
                languageSettings {
                    optIn("kotlin.uuid.ExperimentalUuidApi")
                }
            }
    }
    
    ...
    
    ksp {
        arg("kotlin.uuid.ExperimentalUuidApi", "")
    }
    a
    • 2
    • 3
  • a

    Alejandro Serrano.Mena

    09/01/2025, 10:09 AM
    A beta release for 2.2.0 (namely, 2.2.0-beta.3) is now out. If nothing comes up, we'll publish the final release in two weeks, alongside release announcement and notes. For the curious, these auto-generated release notes give you a glimpse of the new or improved functionality.
    👏 5
    🚀 2
    arrow intensifies 10
  • m

    Manuel

    09/01/2025, 8:00 PM
    Hello, all! I have a question about intended usage of the
    singleton
    dsl I couldn't find any example usages or documentation. I found some places in my code base where it could be useful but I was a little perplexed by the type parameter on the
    SingletonRaise<A>.()
    receiver. I wrote up some mock code to illustrate how I would expect it to work but it doesn't compile due to the indicated line:
    Copy code
    val enableSomething: Boolean = singleton(
      raise = { false }, // <-- ignores resulting raises from `block`
      block = {
        ensure(conditionA)
        ensureNotNull(someValue)
        // do some logging or tracing side-effect
        ensure(conditionB) {
          println("The condition has not been met") // <- Boolean is expected to return here but that value is ignored anyway?
        }
        true
      },
    )
    Does it make more sense to have
    SingletonRaise<A>.()
    be
    SingletonRaise<Unit>.()
    instead, like it is for
    impure
    ?
    p
    r
    a
    • 4
    • 7
  • d

    Daniel Pitts

    09/07/2025, 3:56 PM
    I'm looking to adopt Arrow in a small hobby project (vector graphics editor), and have a some of question. I have a couple of use cases that might be simplified as an "Either". Do these make sense to implement in terms of Either? 1. A "Ref<T>" type that is either a ByName<T>(String), or a Value<T>(T). 2. A "MultipleOr<T>" type that is used to distill the distinct value shared among a collection, or a marker that there is
    Multiple
    . Used in the UI when a user selects multiple objects, and may want to update a property on them in bulk, they'll want to know if the value was already the same. The other question is an whether optics can effectively handle my data model. I have a nested object tree with a
    sealed interface Node
    , which has has different types of nodes, and some of those types will also have Node children. This will be the data model powering a Swing UI (almost directly). Will optics/lenses perform well enough for real time UI interaction, or will I want to have the UI state implemented in a different paradigm?
    y
    • 2
    • 1
  • d

    Daniel Pitts

    09/07/2025, 8:02 PM
    Is there a way to have a recursive Traversal? Specifically something like
    children.every andRecursively { it.children.every }
    ? I can do something manual with DeepRecursiveFunction, but that feels like I might be missing a cleaner way.
    s
    a
    • 3
    • 4
  • d

    Daniel Pitts

    09/08/2025, 1:35 PM
    Is there a concept of "empty" traversal? I have a few similar use-cases, but one of them doesn't need one of the operations I'm performing.
    Copy code
    fun <A> Copy<A>.doOperation(mainTraversal: Traversal<A, B>, optionallySecondTraversal: Traversal<A, C>)
    Most off the types need to have the second traversal transformed, but just one doesn't. I've made optionallySecondTraversal nullable for now, but it would make things nicer if I could just pass in an emptyTraversal().
    s
    • 2
    • 2
  • d

    Daniel Pitts

    09/08/2025, 2:03 PM
    Is there a "cookbook" for Arrow idioms? I feel like there is a bunch of basic syntax that is difficult to discover, but would be useful for reference.
    👀 1
    a
    • 2
    • 3
  • s

    strindberg

    09/08/2025, 2:34 PM
    I am sure I'm missing something trivial, but now I've been struggling for a while experimenting with context parameters and Arrow (2.2.0-beta.3). I can't get the following to work, although I have tried a number of variants:
    Copy code
    data class ValidationError(val message: String, val fields: List<FieldError>)
        data class FieldError(val message: String)
    
        context(_: Raise<ValidationError>)
        fun validateInput(input: List<String>) {
            withError({ errors -> ValidationError("Incorrect fields", errors) }) {
                validateFields(input)
            }
        }
    
        context(_: RaiseAccumulate<FieldError>)
        fun validateFields(fields: List<String>) {
            ensureOrAccumulate(fields[0] == "one") { FieldError("One is not one") }
            ensureOrAccumulate(fields[1] == "two") { FieldError("Two is not two") }
        }
    m
    a
    • 3
    • 4
  • s

    strindberg

    09/08/2025, 2:34 PM
    As I hope is evident from the above, I wish to accumulate a list of field errors, and then gather them into a ValidationError object on the level avove.
  • s

    strindberg

    09/08/2025, 2:36 PM
    The error when calling
    validateFields()
    is "No context argument". I have not found a way to specify it.
  • s

    strindberg

    09/08/2025, 3:03 PM
    To be more clear: the problem is not calling
    validateInput
    , but the fact that I find no (simple) way of making the compiler happy when I call `validateFields`from within
    validateInput
    .
  • d

    Daniel Pitts

    09/09/2025, 12:27 AM
    Optics and coroutine flows question: Does this look like a good idea or a bad idea:
    Copy code
    operator fun <T, R> Flow<T>.get(lens: Lens<T, R>) = map { lens.get(it) }.distinctUntilChanged()
    operator fun <T, R> Flow<T>.get(traversal: Traversal<T, R>) = map { traversal.getAll(it) }.distinctUntilChanged()
    
    // Example usage:
        private fun <T> names(of: Optional<ProjectState, ProjectSpec>. () -> Optional<ProjectState, List<Named<T>>>) =
            projectState[ProjectState.spec.notNull.of().every.name()]
    
        override val availableNamedDrawings = names { drawings }
        override val availableNamedPaints = names { paints }
        override val availableNamedStrokes = names { strokes }
        override val availableNamedStyles = names { styles }
  • o

    Olaf Gottschalk

    09/09/2025, 9:41 AM
    Quick question for all of you: as a functional-oriented programmer, I love to use the NonEmpty... variants of Lists and Sets much more then the "normal" ones, whenever it is a business requirement that there is at least one entry. So, I frequently revisit my code and change signatures to be a
    NonEmptyList
    rather than a
    List
    . A byproduct that I do not like that much is that when these elements are used in user output in simple
    println
    or logs, the
    toString()
    output changes from
    Copy code
    List -> [foo, bar]
    NonEmptyList -> NonEmptyList(foo, bar)
    This is something I wish I could prevent, because more than once I needed to change the logging code to explicitly state
    "${stuff.joinToString()}"
    instead of just
    "$stuff"
    . Is it really good and necessary that Arrow's non-empty variants print their own name in their
    toString()
    implementations?
    🤔 1
    r
    s
    +3
    • 6
    • 25
  • d

    Daniel Pitts

    09/09/2025, 1:43 PM
    Strange bug with optics ksp plugin. If this is the only class in a package, the optics fail to generate. Note the
    breaks
    field uses inferred type.
    Copy code
    @optics
    data class Demo(val intValue: Int) {
        companion object {
            val breaks = Demo.intValue // If defined as `val breaks:Lens<Demo, Int>`, it works.
        }
    }
    Even more strangely, if I have any other optics in the same package that shares a named focus, it fixes all of them.
    Copy code
    @optics
    data class Fixes(val intValue: String) { companion object }
    a
    • 2
    • 6
  • p

    phldavies

    09/09/2025, 9:19 PM
    Despite the compiler complaining
    Tail recursion optimization inside try/catch/finally is not supported.
    for a normal try/catch, it seems it does work when the try/catch is inlined a la
    arrow.core.catch
    or
    arrow.core.recover
    . The bytecode generated does seem to be a tail-recursive loop. arrow intensifies
    y
    s
    a
    • 4
    • 4
  • m

    Manuel

    09/19/2025, 12:01 AM
    Is there any appetite for something similar to this in the library?
    Copy code
    inline fun <T> recover(
      recover: () -> T,
      block: IgnoreErrorsRaise<Null>.() -> T,
    ): T = nullable { ignoreErrors { block() } } ?: recover()
    Maybe it already exists? I'm still on Arrow
    v1.2.4
    . It's a pattern I find myself using often but the nullable reads a bit weird when you see it inlined
    nullable { } ?:  fallback
    because the DSL isn't being used for any kind of nullability, just convenience.
    y
    • 2
    • 5