kushalp
06/03/2020, 9:44 PMIO<A>
, where A
is some enum
having 3 different states: Complete
, Error
and CustomError
. I want to retry the function until either Complete
is returned, or a duration exceeded condition is true. What is the best way to do that with IO
?Clarence Dimitri Charles
06/04/2020, 9:02 AMClarence Dimitri Charles
06/04/2020, 9:40 AMtalk▾
tim
06/04/2020, 5:09 PM.map { someOp(); it }
the approach?pakoito
06/04/2020, 11:41 PMmattmoore
06/04/2020, 11:53 PMXuc Xiem
06/05/2020, 1:55 AM.k()
as much as possible in the following example:
val m = mapOf("a" to listOf(1, 2).k(), "b" to listOf(3).k()).k()
val n = mapOf("a" to listOf(4).k(), "c" to listOf(5, 6).k()).k()
val p = MapK.semigroup<String, ListK<Int>>(ListK.semigroup()).run { m + n }
Xuc Xiem
06/05/2020, 1:27 PMEither
like this:
fun f(): Either<Exception, A> = try {
// do something
Either.right(a)
}
catch (e: Exception) {
Either.left(e)
}
Is that the correct way to use Either
? Is there anything more suitable than Either for that purpose (wrapping a value and catching all exceptions)?tim
06/06/2020, 3:29 PMXuc Xiem
06/06/2020, 10:19 PMval eitherList: List<Either<Exception, String>> = TODO()
to a List<String>
? Someone on StackOverflow (I think) suggested:
eitherList
.filterIsInstance<Either.Right<String>>()
.fold(emptyList()) { acc, right -> right.fold({ acc }, { acc + it }) }
Is there any better way?julian
06/09/2020, 5:55 PMf3
. It seems like there might be a named pattern for what it's doing. It kind of behaves like partially
, except it defers the partial application till later. Then it partially applies to f2 the result of executing the deferred function (when that happens).
If such a pattern exists, what's its name? Do helper functions already exist in Arrow to do this for me? Basically, is there a better way?
Thanks much!tim
06/10/2020, 8:47 AM@Coercion
is not available now is it, if it is which package can I find it in?pakoito
06/10/2020, 1:44 PMpakoito
06/10/2020, 3:54 PMtim
06/10/2020, 4:59 PMjulian
06/10/2020, 7:25 PMModule.data
or Module.domain
be lazy evaluated, would there still be a way to have Module
implement Data
and Domain
?tim
06/11/2020, 4:53 PMAlexander Levin
06/12/2020, 9:24 AMPhBastiani
06/12/2020, 1:40 PMcopy
method is the most idiomatic.
I noticed a wrong proposal of the IDE: sometimes IntelliJ proposes to remove the suspend
modifier when it is necessary 😕
Feedback appreciated !Joram Visser
06/13/2020, 11:00 PMeffectfulProgram: IO<E, A>
I could do effectfulProgram.unsafeRunSync()
to run the program from a none suspended context. (For example an endpoint in a framework without coroutines.) Now I am trying out the new Arrow Fx Coroutines lib and transformed my program to effectfulProgram: suspend () Either<E, A>
. How do I run it? 😅carlos cdmp
06/14/2020, 4:20 PMraulraja
06/15/2020, 12:55 PMRobert
06/15/2020, 1:09 PMCLOVIS
06/15/2020, 1:18 PMinterface Event {
val start: ...
val end: ...
val canSubscribe: Boolean
suspend fun subscribe()
}
But that's a lot of boilerplate per feature, and since I want to learn Arrow, I'm thinking there must be a better way.
What do you think of:
interface Event {
val start: ...
val end: ...
fun subsribe(): Either<UnsupportedOperationException, IO<Unit>>
}
Jörg Winter
06/17/2020, 12:25 PMsuspend fun either(): Either<PersistenceError, ProcessedUser> =
Either.fx {
val user = !fetchUser()
val processed = !user.process()
processed
}
.. so I added arrow-fx (SNAPSHOT) to my dependencies, but where does the bind-operator !
come from ? IntelliJ doesn't seem to find it.stojan
06/17/2020, 4:19 PMSrki Rakic
06/17/2020, 4:44 PMIO<Either<InvalidCommand, Command)>>
as an input to a function that takes Command
as a parameter and returns IO
return EitherT.monad<ForIO, DomainError>(IO.monad()).fx.monad {
val (command) = EitherT(commandFrom(commandType, commandString))
val (eventRecord) = EitherT(commandHandler.handle(command).map { it.right() })
eventRecord
}.value().fix()
.map { result -> result.fold({ Response.Error(it.toString()) }, { Response.Success(it) }) }
.unsafeRunSync()
Does this seem like the right approach?Srki Rakic
06/17/2020, 5:21 PMinline fun <L, F> EitherT.Companion.monad(MF: Monad<F>): EitherTMonad<L, F>
inline fun <L, F> EitherT.Companion.monad(MF: Monad<F>): EitherTMonad<L, F>
tim
06/17/2020, 5:38 PMval numbers = listOf(1, 2, 3, 4)
val strings = numbers.map { somethingThatReturnsEither(it) }
// Here I'd like to map strings and put Lefts into one list and Rights into another list
return Tuple2(failures, successes)
Hopefully that makes sense. I could just do a forEach and put everything into lists manually, but I'm hoping there's an FP way hereTrond Engell
06/18/2020, 10:50 AMNonFatal
. I can understand if you really want to handle InterrupedException
you might want to do that more explicitly, but what about errors that are not listed here (excluding subclasses)? Are they not fatal and to be thrown?
fun NonFatal(t: Throwable): Boolean =
when (t) {
is VirtualMachineError, is ThreadDeath, is InterruptedException, is LinkageError -> false
else -> true
}
Trond Engell
06/18/2020, 10:50 AMNonFatal
. I can understand if you really want to handle InterrupedException
you might want to do that more explicitly, but what about errors that are not listed here (excluding subclasses)? Are they not fatal and to be thrown?
fun NonFatal(t: Throwable): Boolean =
when (t) {
is VirtualMachineError, is ThreadDeath, is InterruptedException, is LinkageError -> false
else -> true
}
simon.vergauwen
06/18/2020, 10:56 AMEither.catch
these fatal errors won’t be caught, but will continue to propagate.Trond Engell
06/18/2020, 11:00 AMsimon.vergauwen
06/18/2020, 11:02 AMtry/catch
with e: Throwable
then it’s a good idea to use this predicate as well.
We typically do the following.
try {
donSomething()
} catch(e: Throwable) {
ifError(e.nonFatalOrThrow())
}
Trond Engell
06/18/2020, 11:07 AMfun <Result> Either.Companion.fromTry(block: () -> Result): Either<Throwable, Result> =
try {
block().right()
} catch (throwable: Throwable) {
throwable.nonFatalOrThrow().left()
}
simon.vergauwen
06/18/2020, 11:14 AMTrond Engell
06/18/2020, 11:21 AMsimon.vergauwen
06/18/2020, 11:24 AMNonFatal
to be captured in Left<Throwable>
?throwable.nonFatalOrThrow()
returns a NonFatal
exception, or it rethrows if the above predicate matches.
That means that all exceptions, except for VirtualMachineError
, ThreadDeath
, InterruptedException
& LinkageError
will be rethrown. All other exceptions will be returned as Left(exception)
.Trond Engell
06/18/2020, 11:31 AMLeft<Exception>
and to throw all Error
. In that case the predicate might not match all errors and I must do so manually. I am trying to wrap my head around this and I am unsure if this is good practice. I am sorry if this is not very Arrow-specific.simon.vergauwen
06/18/2020, 11:34 AMTrond Engell
06/18/2020, 11:50 AMError
in any way. Just throw them and crash/exit application to avoid bad state. I just figured there must be a reason why the predicate is defined like this
is VirtualMachineError, is ThreadDeath, is InterruptedException, is LinkageError -> false
..and not like this
is Error, is InterruptedException -> false
It must mean that there is some Error
that is not considered fatal.