Ville Peurala
04/19/2023, 8:59 AMsimon.vergauwen
04/19/2023, 9:16 AMmap
or flatMap
. Where flatMap
is only still used for data types that contain 0-n
values.
If you're defining a data type that requires short-circuit behavior, then you can integrate with the Raise
DSL. https://arrow-kt.io/learn/typed-errors/working-with-typed-errors/#creating-your-own-error-wrappers (more info in the current PR, https://github.com/arrow-kt/arrow-website/pull/173).
If you're modelling something concurrent like Resource
or Saga
, then you need to integrate with KotlinX Coroutines and rely on suspend
. This typically entails creating an interface DSL that implements the cases of the ADT using functions and then having the cases of the interpreter implemented by the functions of the interface. Here is a tiny example, of a Timed
data type.
When we're dealing with regular data like Pair/Triple, not effect types than Functor is often considered an anti-pattern.
If you have a specific example, then perhaps I am able to help.Ville Peurala
04/19/2023, 9:26 AMdata class CappedAmount<T>(
val uncapped: T,
val capped: T
): Functor<T> {
override fun fmap(_f_: Function<T>) = CappedAmount(f(uncapped), f(capped))
}
Ville Peurala
04/19/2023, 9:32 AMVille Peurala
04/19/2023, 9:34 AMPair
or Triple
, I want my domain classes to have good names.simon.vergauwen
04/19/2023, 9:39 AMPair
anyway. What I meant was that it's considered an anti-pattern for Pair
since it's defined over A, B
and Functor#map
is then only defined over A
or B
so it doesn't offer a useful operation.
I would also recommend using a specific domain type, rather than tuples. Unless you're in an intermediate operation, or for destructuring purposes only.
It's not possible in Kotlin to offer the API you're looking for in a generic way. This requires HKTs. I am also not entirely sure if the operation you describe here is a valid Functor
🤔 I guess it would adhere to the laws though (on top of my head).
Anyhow, Kotlin cannot offer such facilities so neither can Arrow. We've felt that since the removal of this abstractions 5 years ago it resulted in more idiomatic Kotlin.
Typically for your use-case we would just define a fmap
function like you've shown here to generalise some boilerplate.Ville Peurala
04/19/2023, 9:40 AM