raulraja
07/17/2025, 5:19 PMJonathan
07/18/2025, 4:50 PMJokubas Alekna
07/21/2025, 3:46 PMMichael Friend
07/24/2025, 5:48 PMHttpClientError
(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?sindrenm
07/29/2025, 1:08 PMKev
07/30/2025, 7:05 AMUlrich Schuster
07/31/2025, 10:07 AMEitherNel
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?sindrenm
08/01/2025, 10:47 AMdave08
08/12/2025, 5:34 AMHuib Donkers
08/14/2025, 5:18 PMcontract
specified for Either::getOrNull
. It seems incorrect in case B
(right) is nullable.
For reference:
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..
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))
?dave08
08/17/2025, 7:19 AMErik Dreyer
08/20/2025, 10:19 AMCarter Hudson
08/20/2025, 7:17 PMErik Dreyer
08/24/2025, 3:57 PMDirk
09/01/2025, 8:49 AM@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:
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", "")
}
Alejandro Serrano.Mena
09/01/2025, 10:09 AMManuel
09/01/2025, 8:00 PMsingleton
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:
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
?Daniel Pitts
09/07/2025, 3:56 PMMultiple
. 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?Daniel Pitts
09/07/2025, 8:02 PMchildren.every andRecursively { it.children.every }
? I can do something manual with DeepRecursiveFunction, but that feels like I might be missing a cleaner way.Daniel Pitts
09/08/2025, 1:35 PMfun <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().Daniel Pitts
09/08/2025, 2:03 PMstrindberg
09/08/2025, 2:34 PMdata 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") }
}
strindberg
09/08/2025, 2:34 PMstrindberg
09/08/2025, 2:36 PMvalidateFields()
is "No context argument". I have not found a way to specify it.strindberg
09/08/2025, 3:03 PMvalidateInput
, but the fact that I find no (simple) way of making the compiler happy when I call `validateFields`from within validateInput
.Daniel Pitts
09/09/2025, 12:27 AMoperator 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 }
Olaf Gottschalk
09/09/2025, 9:41 AMNonEmptyList
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
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?Daniel Pitts
09/09/2025, 1:43 PMbreaks
field uses inferred type.
@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.
@optics
data class Fixes(val intValue: String) { companion object }
phldavies
09/09/2025, 9:19 PMTail 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 intensifiesManuel
09/19/2025, 12:01 AMinline 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.