phldavies
10/25/2022, 6:40 PMresult {}
computation (arrow 1.1.3, kotlin 1.7.20, but also occurs in 1.6.21 at least). Notably, if you switch dispatcher within the computation as follows:
result {
withContext(<http://Dispatchers.IO|Dispatchers.IO>) {}
1
}
you end up with nested Success(Success(1))
, despite the return type being correctly Result<Int>
.
Weirdly, using the following in it’s stead
private suspend inline fun <A> result(crossinline f: suspend ResultEffectScope.() -> A): Result<A> =
effect { f(ResultEffectScope(this)) }.toResult()
Works as expected, but looks to be identical in implementation.
I’ve also realised I still have no idea when best to use runCatching {}
vs result {}
vs Either.catch {}
😳CLOVIS
10/26/2022, 1:37 PMCLOVIS
10/31/2022, 11:33 AMEffectScope<Failure>.() -> Unit
or:
() -> Either<Failure, Unit>
I think the first one is clearer that "it's just validation code", what do you think? Is there any official recommendation?
The first one also doesn't need the user to call bind
, which they may forget since there is no proper result.Davide Giuseppe Farella
10/31/2022, 1:33 PMkspCommonMainMetadata(libs.arrow.optics.ksp)
add("kspJvm", libs.arrow.optics.ksp)
then I’ve added
kotlin{
sourceSets.all {
kotlin.srcDir("build/generated/ksp/${this.name}/kotlin")
}
}
and I see the code generated under
• generated/ksp/jvm/jvmMain/kotlin
• generated/ksp/metadata/commonMain/kotlin
But the generated code is not resolved
I believe I’m missing something in the setup (?)Alejandro Serrano Mena
11/02/2022, 12:57 PMPiotr Krzemiński
11/04/2022, 10:09 AMDavide Giuseppe Farella
11/05/2022, 11:51 AMplayerFlow.map { player ->
val firstNameLens = Player.name.first
firstNameLens.set(player, "John")
}
If I want to modify also the last name, is there a nicer way than this?
playerFlow.map { player ->
val firstNameLens = Player.name.first
val lastNameLens = Player.name.last
val a = firstNameLens.set(player, "John")
lastNameLens.set(a, "Doe")
}
Kristian Nedrevold
11/05/2022, 1:37 PMkartoffelsup
11/07/2022, 6:58 PMval exponentialBackoff: Schedule<Throwable, Double> = Schedule.exponential(TimeUnit.SECONDS.toNanos(2L).toDouble())
val retrySchedule = exponentialBackoff.jittered()
.whileOutput {
TimeUnit.NANOSECONDS.toSecods(it.toLong()) < 10.0
}
.untilInput {
when (it) {
is ApiException -> it.statusCode in 400 until 500
...
else -> false
}
the above never stops on the whileOutput condition (using this at work and don't have the code handy, it looks at least similar to above :D)Slackbot
11/08/2022, 7:40 AMKristian Nedrevold
11/09/2022, 9:47 PMGiorgos Makris
11/11/2022, 10:59 AMJörg Winter
11/12/2022, 10:44 AMfun mytimer() = Schedule.forever<String>().delay { duration ->
Duration.Companion.seconds(5)
}
Hi all,
What is the input argument 'duration'.. when has it a value other than 0s (in this example it is always 0s) ?Youssef Shoaib [MOD]
11/13/2022, 9:02 AMYoussef Shoaib [MOD]
11/13/2022, 11:19 AMFoo<Foo<T>> -> Foo<T>
? That proof is valid in that it's not cyclical, but if you're working backwards from knowing that we need a Foo<T>
then I can't see how to ascertain that this proof isn't applicable (because the proof is applicable if e.g. there's a Foo<Foo<Foo<T>>>
that can be created). One can obviously look at other proofs that provide a Foo of something and use those as a starting point, but what if there's a proof Bar<T> -> Foo<T>
and the only proof returning Bar<T>
requires a Foo<Foo<T>>
(akin to mutual recursion)
Also will arrow-proofs support something like
@Inject fun <A, B> test(@Given bar: Bar<A, B>, @Given foo: Foo<A>): B = bar.someFunctionThatTakesFooAndReturnsB(foo)
As in, will type parameter be properly substituted in like that and allowed to influence the resolution of what proof to use for foo
, or will the caller have to specify A
and B
for the call to resolve correctly? Looking around the plugin code I can see that for every Inject
function you generate one with default arguments, so I can't really see how this use case could be supported.Lee Taehoon
11/14/2022, 7:10 AM@optics
data class Company(val name: String, val address: Address) {
companion object
}
// Auto generated code
public inline val com.example.contextreceiversample.Company.Companion.name: arrow.optics.Lens<com.example.contextreceiversample.Company, kotlin.String> inline get() = arrow.optics.Lens(
get = { company: com.example.contextreceiversample.Company -> company.`name` },
set = { company: com.example.contextreceiversample.Company, value: kotlin.String -> company.copy(`name` = value) }
)
public inline val com.example.contextreceiversample.Company.Companion.address: arrow.optics.Lens<com.example.contextreceiversample.Company, com.example.contextreceiversample.Address> inline get() = arrow.optics.Lens(
get = { company: com.example.contextreceiversample.Company -> company.`address` },
set = { company: com.example.contextreceiversample.Company, value: com.example.contextreceiversample.Address -> company.copy(`address` = value) }
)
I tried to reference Company.name
, but Android Studio can not find it.
Still, build and run normally.
How can I solve this problem? I had tried Invalid Caches and Restart
.Daniel Berg
11/15/2022, 11:05 PMeither
and either.eager
are now deprecated? The replacement is effect { … }.toEither()
and eagerEffect { ... }.toEither()
? Is that right?Racci
11/17/2022, 7:34 AMTom Davis
11/17/2022, 10:03 PMList<() -> Validated<E, A>>
which i want to transform into ValidatedNel<E, A>
by:
1. specifying invalid value if the list is empty
2. calling items until the first valid value is encountered
3. aggregating invalid values until (2)
4. ignoring items after (2)
i can come up with an "ugly" way to do this easily enough, but i'm curious if there's a nice fluent pattern for it. thanks in advance!Jorge Bo
11/18/2022, 12:43 PMeither<ReservationError, Unit> {
//do some logic
}.mapLeft {
meterService.incrementExitError("online")
it
}.map {
meterService.incrementExitRequests("online")
}
Marc Plano-Lesay
11/18/2022, 11:04 PMtrue
, I want to evaluate something and return it as a Some
, otherwise I want to return a None
. Here's a pretty trivial implementation that might be clearer:
fun <A> Option.Companion.cond(condition: Boolean, value: () -> A): Option<A> = if (condition) {
value().some()
} else {
None
}
Is there anything built-in that I'm missing?Jörg Winter
11/20/2022, 9:07 AMrepeat
(think AtomicBoolean
or something similar). So the Schedule actually continues, but the effect to be run by repeat
has to evaluate that switch inside it's own logic.
What I am looking for is something like an pause
operator, which completely stops the Schedule until some condition gets true again.
Is this semantic possible with the current operators somehow or could that be added in the future ?trevjones
11/21/2022, 6:31 PMEduardo Barbosa
11/24/2022, 3:58 PMchiroptical
11/25/2022, 3:25 PMCoroutineScope.windows
and dayOne
(there are edge cases in strictlyIncreasing
that aren't important for this conversation). Second, is it possible to fold in parallel as well? I tried creating two actors, passing inputs to them, and then combining them at the end but it just didn't do anything. I am incredibly open to suggestions here🧵CLOVIS
11/25/2022, 3:52 PMKristian Nedrevold
11/25/2022, 5:50 PMWesley Hartford
11/25/2022, 11:26 PMEffect
and the arrow-fx
projects? I've been using Effect
to model effects such as calls to a database or web service. Is there a recommended way to use the features of arrow-fx
to add retries to an Effect
?jem
11/27/2022, 8:48 AMsimon.vergauwen
11/28/2022, 10:41 AMValidated
and integrating its functionality into Either
. https://github.com/arrow-kt/arrow/pull/2795#issuecomment-1328864003
Feedback, and thoughts are very welcome 🙏simon.vergauwen
11/28/2022, 10:41 AMValidated
and integrating its functionality into Either
. https://github.com/arrow-kt/arrow/pull/2795#issuecomment-1328864003
Feedback, and thoughts are very welcome 🙏stojan
11/28/2022, 12:39 PMzip
function instead of the current extension function?
I think it existed in earlier versions of arrow but was replaced by extension functions at one point
e.g. zip
and combine
from kotlinx coroutines are top level functionssimon.vergauwen
11/28/2022, 12:48 PMzip(fa, fb, fc) { a, b, c -> }
instead of fa.zip(fb, fc) { a, b, c -> }
?zip
. I.e. on Iterable<A>
stojan
11/28/2022, 12:59 PMIterable
example, it's always two of them that are zipped... so extension function makes sense there IMO
but when we have them with arity 2-7, top level makes more sense IMOsimon.vergauwen
11/28/2022, 1:05 PMcombine
is defined as an extension for arity-2 and for arity 3+ it's top-level 🤯
https://kotlinlang.org/api/kotlinx.coroutines/kotlinx-coroutines-core/kotlinx.coroutines.flow/combine.htmlvararg
which is different, since that doesn't allow independent functions like Either#zip
.stojan
11/28/2022, 1:10 PMI wish there were guidelines for this, or that the Jetbrains people would document why these functions are shaped differently in Kotlin Std and KotlinX.maybe we can ask in the #stdlib channel?
simon.vergauwen
11/28/2022, 1:11 PMflowA.zip(flowB) { a, b -> }
to zip(flowA, flowB, flowC) { a, b, c -> }
stojan
11/28/2022, 1:15 PMphldavies
11/28/2022, 2:15 PMValidated<A>.zip(b: V<B>, c: V<C>, (A, B, C) -> R)
odd that it feels like it elevates A
other the others as different. If you want to rearrange the arguments to the block you end up swapping receivers around.simon.vergauwen
11/28/2022, 2:17 PMphldavies
11/28/2022, 3:33 PMval username = fields.required("username").andThen(String::parseUsername)
val email = fields.required("email").andThen(String::parseEmail)
val age = fields.required("age").andThen(String::parseAge)
email.zip(username, age, ::CreateUserRequest)
Why is email
different to username
or age
in this case? If I wanted to updated CreateUserRequest
to take username
first, I’d need to update the receiver of zip
rather than just the argument ordering. It just feels like the first argument being bound is treated specially. For this reason, I sometimes find myself adding a top-level zip(A, B, C, (a, b, c) -> R)
helper to make it feel a little more natural. As an example, kotest has a top-level Arb.bind(Gen<A>, Gen<B>, Gen<C>, (a, b, c) -> R) -> Arb<R>
rather than a Gen<A>.zip(...)
simon.vergauwen
11/28/2022, 3:39 PMEither.zip(fa, fb, fc) { a, b, c -> }
would make more sense to you? I guess this is similar to what @stojan was saying.
One of the original reasoning, besides getting inspiration from Iterable<A>#zip
was because fa.zip
is easier to find through auto-completion.phldavies
11/28/2022, 3:50 PMValidated
I initially looked for an extension off the Validated
companion, iirc.
I can certainly see your reasoning though, given stdlib provides Iterable<A>.zip(Iterable<B>, (A, B) -> C)
and arrow extends that with n-arity forms with the receiver maintained.simon.vergauwen
11/28/2022, 3:51 PMmapN(fa, fb, fc) { a, b, c -> }
or with special syntax fa @ fb @ fc
(returning a Tuple).stojan
11/28/2022, 3:52 PMI initially looked for an extension off theAFIK the companion object strategy is not used in the standard lib or kotlinx coroutines, and the kotlin team suggests top level functions insteadcompanionValidated