Sagar Suri
01/18/2020, 2:23 AMboolean
. Should I wrap the return type with Either
or what will be a better return type?Christian Maus
01/18/2020, 7:20 PMthan_
01/20/2020, 3:00 PMcontinueOn(NonCancellable)
? this snippet prints only STARTED :/
import <http://arrow.fx.IO|arrow.fx.IO>
import arrow.fx.extensions.fx
import kotlinx.coroutines.NonCancellable
import kotlinx.coroutines.delay
val io = IO.fx {
continueOn(NonCancellable)
effect { println("STARTED") }.bind()
effect { delay(10000) }.bind()
effect { println("FINISHED") }.bind()
}
val disposable = io.unsafeRunAsyncCancellable { }
disposable()
Fabian
01/20/2020, 3:07 PMmonad-comprehensins
on StateMonad
?
I'm having some code that when implemented with flatMap
s compiles and run without issues BUT with monad-comprehensions throws
java.lang.NoSuchMethodError: arrow.typeclasses.Monad.getFx()Larrow/typeclasses/MonadFx
So I wanted to check for a reference exampleJannis
01/20/2020, 8:27 PMraceN
correctly:
IO.fx {
dispatchers().io().raceN(timer().sleep(10.seconds).followedBy(effect { println("Hello") }), effect { println("Hello world") })
.fork().bind().join().bind()
}.suspended()
This code fails with a cancellation exception after one of the effects has occured. The same code without the extra fiber does not. suspended()
or not also changes nothing, unsafeRunSync will also fail.kyleg
01/21/2020, 6:44 PMTry
so that it does not advise this anymore (Try
is deprecated).
In a Prism documentation that uses Try
, there is an example that uses pTrySuccess
, which allegedly lives in arrow.optics
. However, I have cloned the Arrow repo and have searched the entire codebase for this string. It only appears in arrow-optics/prism/README.me
but in no actual code. I can’t find it in the git history for Optics.kt
either.
Does anyone remember what this function was supposed to do? If I’m already replacing Try
with Either
in many places, I need to get this code working so I can make sure my new documentation is functional code.addamsson
01/21/2020, 6:59 PMdnowak
01/21/2020, 10:42 PMEitherT
to perform mapLeft
.Hiosdra
01/22/2020, 11:50 AMMark Fisher
01/22/2020, 12:36 PMfun <F> getSongUrlAsync(MS: MonadDefer<F>) =
MS { getSongUrl() }
but this doesn't compile for me, i'm getting (on a similar function) - see below
What am I doing wrong, or are the docs wrong? I'm a bit lost tbh
The type import for MonadDefer is arrow.fx.typeclasses.MonadDefer
Jannis
01/22/2020, 2:21 PMEval
for stacksafety and optimization and provides primitives to render Documents with applicative effects (for rendering straight to e.g. an output stream).
The docs currently include a landing page, a getting started guide and a full api reference. Everything else in the docs is wip, so if you have any questions feel free to ask directly ask me (or open issues). Feedback is much appreciated!Mark Fisher
01/22/2020, 3:02 PMclass ArrowRxTests {
@Test
fun `comprehension with arrow and rx`() {
val x = SingleK.fx {
val (count) = getCountSingle // this is an async call using a SingleK.monadDefer
val newCount = increment(count) // this is an async call returning Single<Int>.... how do i use it here?
newCount
}.value()
assertThat(x.blockingGet()).isEqualTo(2)
}
private fun getCount() = 1
private fun <F> getCountAsync(MS: MonadDefer<F>) = MS.later { getCount() }
private val getCountSingle: SingleKOf<Int> = getCountAsync(SingleK.monadDefer())
private fun increment(i: Int): Single<Int> = Single.just(i + 1)
}
This works if increment
just returns an int, but how do I use increment() in the comprehension when it already returns a Single?
I want to somehow keep the flow of the code inside SingleK.fx {}
but using functions that return Rx typeskyleg
01/22/2020, 5:52 PMTry
is deprecated, is the preferred replacement for (non-suspending) Try { … }
:
1. an explicit try { Either.right(…) } catch(e) { Either.left(…) }
or
2. runBlocking { Either.catch { … } }
(which is a suspend fun)Attila Domokos
01/22/2020, 6:14 PMEitherT<ForIO>
extensively. I really like the code I have, however, some people are lost with monad transformers. I tried to dummy down the example to use IO<Either<A, B>
, however, the code is not very attractive. Check out the functions run
using EitherT and run2
using IO<Either> types. Why do I need to call unsafeRunSync
in function run2
to call that code? Does flatMap
invalidate the fx
context? https://github.com/adomokos/kotlin-sandbox/blob/ad/io-either/src/main/kotlin/sandbox/explorer/App.kt#L65-L98Luke Rohde
01/22/2020, 7:41 PMMark Fisher
01/23/2020, 10:48 AM@Test
fun `concurrent arrow and rx`() {
val x = SingleK.fx {
val requiredValue = !getCountSingle
println("network call A")
val networkCallAValue = !pauseAndIncrement(requiredValue).k()
println("network call B")
val networkCallBValue = !pauseAndIncrement(requiredValue).k()
networkCallAValue + networkCallBValue
}.value()
assertThat(x.blockingGet()).isEqualTo(4)
}
private fun pauseAndIncrement(i: Int): Single<Int> {
println("Entering pause...")
Thread.sleep(2000)
println("... returning single")
return Single.just(i + 1)
}
getCountSingle
in this context should block the subsequent assignments until it is available (this is fine) but its value should be usable by the 2 subsequent calls which I'd like to happen concurrently as they are independent, and I just need to block on the result of them both.
Is there a nice way of doing this without it becoming spagetti code?Satyam Agarwal
01/23/2020, 2:15 PMTry { … }.toEither()
with IO { … }.attempt().unsafeRunSync()
in the clients/repositories
2. Start Replacing Either from services with IO and remove unsafeRunSync()
and bring it to services.
3. Eventually remove unsafeRunSync()
and bring them finally to controllers.
4. And finally get rid of springboot ❤️
I have worked with unsafeRunSync
before in production for very small things (mostly one time things like migrations, imports/exports where I couldn’t do without springboot 💢), so I am comfortable and have not seen any problems, but with above, my apis can get affected, consequently my user-base.
I am basically wondering about this line from doc
**NOTE** this function is intended for testing, it should never appear in your mainline production code!
Can you guys help me with deciding if this makes sense and is sane thing to do, and what kind of problems I can see with this approach.aballano
01/24/2020, 11:22 AMAttila Domokos
01/24/2020, 5:24 PMBruno
01/24/2020, 9:20 PM[1..10]
|> List.map (add 2)
|> List.map (mult 3)
My attempts:
#1
(1..10)
.pipe { it.map { add(2) } }
.pipe { it.map { mult(3) } }
#2
(1..10)
.map { add(2) }
.map { mult(3) }
What am I missing?
I'd expect a list like:
[9,12,15,18,21,24,27,30,33,36]
, but instead get a List<(Int) -> Int>
mbrandonw
01/27/2020, 2:25 PM@optics
to generate optics for generic data classes and sealed classes. The generated code has compiler errors. 1) is this right? and 2) are there alternatives to this besides writing the optics by hand?pakoito
01/27/2020, 4:46 PM// TODO which we need to have access to the implementation of map in Optionyes! it's also a fun exercise not to call
fix()
and see a stackoverflow exception because the function calls itselfSatyam Agarwal
01/27/2020, 6:11 PMkyleg
01/27/2020, 7:56 PMBruno
01/28/2020, 9:27 AMfun add(a: Int, b: Int): Int = a + b
suspend fun main1(args: Array<String>) =
IO.fx {
val sc = Scanner(System.`in`)
val nextInt = effect { sc.nextInt() }
val added = IO.applicative()
.map(nextInt, nextInt) { (a, b) -> add(a, b) }.bind()
effect { println(added) }.bind()
}.run { suspended() }
aeruhxi
01/29/2020, 8:52 AMEither.fx() {
val (x) = someLeftValue()
10
} // Left propagates
Either.fx() {
someLeftValue()
10
} // Either.Right(10)
rcd27
01/29/2020, 10:47 AMKotlin
compiler had such feature like implicit
in Scala
, there would be less work for people who do Arrow Meta
? This Scala
feature looks very useful.Hiosdra
01/29/2020, 8:38 PMfun validatePhotoMatch(login: Login, photo: ByteArray): IO<Error, Unit> =
IO.monad<Error>().fx.monad {
val user = !userService.getUserByLogin(login)
val modelVectors = !extractFaceVectors(user)
val unknownVectors = !recognitionService.calculatePhoto(photo)
val resultDto = !recognitionService.calculateDifference(unknownVectors, modelVectors)
!failureOrUnit(resultDto.result)
}.fix()
I cannot make second line: as IO.fx {
. Idea cannot decide if it should be:
IO.Companion.fx(c: suspend IOSyntax<E>.() -> A): IO<E, A>
Or:
IO.Companion.fx(c: suspend ConcurrentSyntax<IOPartialOf<Nothing>>.() -> A): IO<Nothing, A>
Is it some kind of bug with new IO being BIO? Or I do something bad? Type inference should see that there is Error on left side, not Nothing. (I use my own Error class in ADT)
Every method used in for-comprehension is returning IO<Error, x>
Arrow Gradle deps are:
val arrowVersion = "0.11.0-SNAPSHOT"
implementation("io.arrow-kt:arrow-fx:$arrowVersion")
implementation("io.arrow-kt:arrow-fx-reactor:$arrowVersion")
implementation("io.arrow-kt:arrow-mtl:$arrowVersion")
implementation("io.arrow-kt:arrow-mtl-data:$arrowVersion")
implementation("io.arrow-kt:arrow-syntax:$arrowVersion")
implementation("io.arrow-kt:arrow-integration-retrofit-adapter:$arrowVersion")
kapt("io.arrow-kt:arrow-meta:$arrowVersion")
And second:
Maybe add function Either<E, A>.toIO<E, A>()
? There are already functions that map left side of Either to “below” side of IO, but I couldn’t see any mapping Either left to IO left. In BIO it would be very easy. I have written it for my own purpose and can push pull-request to 0.11.0 branch ;)pakoito
01/29/2020, 8:54 PMIO.monad<Error>().fx.monad {
don’t use this, use just IO.fx<MyError> { ... }
pakoito
01/29/2020, 8:59 PM