Satyam Agarwal
02/15/2020, 1:09 PMjava.util.concurrent.Future
?/ Can I convert java’s future to IO ? I know I can alway do IO.invoke { sendFuture().get() }
. I am not exactly able to explain, what I want, But I am looking for something like coroutines/reactor support in arrow-fx, for java’s futuresmelatonina
02/17/2020, 9:46 AMCLOVIS
02/17/2020, 10:50 AMfold
on any Functor, but not all operations can be called on it (there needs to be a default value). So it sounds like fold
is defined neither on a category nor on a morphism but on the pair of both of them?raulraja
02/17/2020, 10:54 AMgabib
02/18/2020, 2:27 PMRodrigo Silva
02/18/2020, 4:33 PMCarter Youngblood
02/18/2020, 10:37 PMGopal S Akshintala
02/19/2020, 3:07 AMDBClient
, which is not in my hands (say a lib impl) and it returns me a concrete type, like IO<String>
. Now I wish to have a generic repo and only commit to a concrete type at the edge of my application, like main()
here. But I get a compiler error in repo as commented below, which is expected. Is there any idiomatic workaround to achieve what I desire for? Thanks.
open class Repo<F>(
private val dbClient: DBClient,
M: Monad<F>
) : Monad<F> by M {
fun get(): Kind<F, String> = fx.monad {
dbClient.get() // vvv Compiler error. This needs to be converted to generic Higher kind
}
}
fun main() {
val repo = Repo(DBClient(), IO.async())
print(repo.get().fix().unsafeRunSync())
}
class DBClient {
fun get() = IO { "abc" }
}
Bob Glamm
02/19/2020, 3:10 PMimport cats._
import cats.data._
import cats.implicits._
import cats.syntax._
import cats.effect._
?raulraja
02/20/2020, 12:05 PMBob Glamm
02/20/2020, 4:51 PMfun <F> F.updateTimezone(ctx: DocumentContext): Kind<F, DocumentContext> where F: MonadThrow<F> { ... }
(with arrow 0.10.x), but IIRC I am waiting for Arrow 1.0 to have the equivalent of Scala's (implicit MT: MonadThrow[F])
, right?CLOVIS
02/20/2020, 5:07 PM.let
is map
on an Option
?.
notation is flatMap
on an Option
Your thoughts?Bob Glamm
02/20/2020, 10:41 PMBob Glamm
02/21/2020, 3:26 PMdnowak
02/22/2020, 1:29 PMmelatonina
02/22/2020, 11:52 PMEither.monad<Exception>().fx {
}
but the IDE says there is no fx
. If I go to the definition of Either.monad()
, I see that it returns a
EitherMonad<L>
, which has a definition for fx
. What's happening? That is an attempt to adapt the code from your comprehension tutorial. If, instead, I'm supposed to use
Either.monad<Any>().binding {
}
then the problem is that I don't thave any binding
method around.Gopal S Akshintala
02/23/2020, 1:05 PMhttps://www.youtube.com/watch?v=VOZZTSuDMFE▾
Manuel Roblek
02/24/2020, 9:48 AMCarter Youngblood
02/25/2020, 5:13 PMKStream<Either<Error, Result>>
and create a Pair
of KStream<Error>
and KStream<Result>
. I was not sure how to accomplish this using Either from arrow. We have some helpers in scala that do this now, and for my learning I wanted to do the same in kotlin - in scala it looks something like this -
def forkValuesEither: (KStream[K, LV], KStream[K, RV]) = (
kStream.flatMapValues(_.left.toSeq),
kStream.flatMapValues(_.right.toSeq)
)
but I was not sure how to get to the value in arrow/kotlin of the either to return.kluck
02/26/2020, 10:22 AMjava.lang.NoClassDefFoundError: arrow/typeclasses/MonadContinuation
at arrow.typeclasses.MonadFx$DefaultImpls.monad(Monad.kt:107)
at arrow.core.extensions.OptionFxMonad.monad(option.kt:223)
at arrow.core.extensions.OptionFxMonad.monad(option.kt:220)
at arrow.core.extensions.OptionKt.fx(option.kt:324)
The incriminated code block:
private fun Option<Duration>.moreThan5Minutes(compared: Option<Duration>) = (isEmpty() != compared.isEmpty()) || Option.fx {
val first = bind()
val second = compared.bind()
abs(abs(first.toMinutes()) - abs(second.toMinutes())) >= FIVE_MINUTES
}.getOrElse { false }
In my gradle.kts:
implementation(io.arrow-kt:arrow-fx:0.10.4)
implementation(io.arrow-kt:arrow-syntax:0.10.4)
Oh, and the test work when run through Android Studio 🤔
Any idea what might be causing this?pakoito
02/26/2020, 1:25 PMpakoito
02/26/2020, 1:26 PMfx
block with a single line !
is the same as just pulling the thing you’re binding outsideGopal S Akshintala
02/27/2020, 2:10 PMEither.fx<L,R>{}
works with only one type of Either<L,R>
. Is there any way to work with different types of Either
to avoid nested fold?
val a: Either<Int, String> = "a".right()
val b: Either<String, Int> = 1.right()
Either.fx<String, Int> {
val bind = a.bind() // ^^^ Compiler Error
b.bind()
}
Jonathan
02/27/2020, 2:29 PMFlow
and Arrow's IO
?
Here is an example of what I'd like to achieve. But it doesn't compilbe because IO.fx
restrict suspension:
val flow: Flow<Int> =
flowOf(1, 2, 3)
fun putStrLn(value: Any?): IO<Unit> =
IO { println(value) }
val program = IO.fx {
flow.collect {
!putStrLn(it)
}
}
fun main() {
program.unsafeRunSync()
}
Gopal S Akshintala
02/28/2020, 11:11 AMfx.async{}
block below:
fun <F> Async<F>.something(): Kind<F, Either<String, String>> = fx.async {
val left = "1-left".left().just()
// I wish to short-circuit here if either above is left
"2-right".right()
}
This is what I could come up with:
fun <F> Async<F>.something2(): Kind<F, Either<String, String>> = fx.async {
Either.fx {
!"1-left".left()
"2-right".right().bind()
}
}
Is there a better way than to use nested blocks?raulraja
02/28/2020, 4:12 PMHugo
02/29/2020, 7:27 PM@Test
fun combineEithers() {
val name = randomEither(null, "Alfredo Lambda")
val phone = randomEither(null, 55555555)
val address = randomEither(null, listOf("1 Main Street", "11130", "NYC"))
val result = Either.applicative<Profile>()
.tupled(name, phone, address)
.fix()
.map { Profile(it.a, it.b, it.c) }
println(result)
}
fun <K> randomEither(left: ResponseError?, right: K): Either<ResponseError, K> {
return if (left != null) {
Either.left(left)
} else {
Either.right(right)
}
}
data class Profile(val name: String, val phone: Int, val address: List<String>)
Gopal S Akshintala
03/01/2020, 7:43 AMFormField
used in this example)?
I could come-up with something like below, using inheritance, but I feel that’s not the ideal way, as I hv to touch the Framework code (Rules<F>
) every time I extend this for a new type. Cc: @raulraja
interface FormFieldValidation<F> : ApplicativeError<F, Nel<ValidationError>> {
...// This has contain FormField.contains, FormField.maxLength, FormField.validateWithEmailRules()
}
interface FormFieldValidation2<F> : ApplicativeError<F, Nel<ValidationError>> {
...// This has contain FormField2.contains, FormField2.maxLength, FormField2.validateWithEmailRules()
}
sealed class Rules<F>(A: ApplicativeError<F, Nel<ValidationError>>) :
ApplicativeError<F, Nel<ValidationError>> by A,
FormFieldValidation2<F>,
FormFieldValidation<F> {
.....
}
pakoito
03/01/2020, 11:34 PMkluck
03/02/2020, 10:28 AMfun childIO() = setState { // -> See <https://github.com/uniflow-kt/uniflow-kt/blob/master/uniflow-core/src/main/kotlin/io/uniflow/core/flow/DataFlow.kt#L93>
onIO { // -> coroutine's IO : suspend fun <T> onIO(block: suspend CoroutineScope.() -> T) = withContext(<http://UniFlowDispatcher.dispatcher.io|UniFlowDispatcher.dispatcher.io>(), block = block)
delay(100)
repository.add("LongTodo")
repository.getAllTodo().mapToTodoListState() // -> fun getAllTodo() : List<Todo>
// -> fun List<Todo>.mapToTodoListState() : TodoListState
}
}
What I'm trying to have is a similar syntax to this, with a setState
taking IO
instead of suspending functions:
fun getAllTodo(): IO<List<Todo>>
fun childIO() = setState { getAllTodo().map { TodoListState(it) } }
Any idea where I should start? I've seen that @Jorge Castillo commented on arrow issues in the uniflow github, maybe he'll know what I'm talking about ^^kluck
03/02/2020, 10:28 AMfun childIO() = setState { // -> See <https://github.com/uniflow-kt/uniflow-kt/blob/master/uniflow-core/src/main/kotlin/io/uniflow/core/flow/DataFlow.kt#L93>
onIO { // -> coroutine's IO : suspend fun <T> onIO(block: suspend CoroutineScope.() -> T) = withContext(<http://UniFlowDispatcher.dispatcher.io|UniFlowDispatcher.dispatcher.io>(), block = block)
delay(100)
repository.add("LongTodo")
repository.getAllTodo().mapToTodoListState() // -> fun getAllTodo() : List<Todo>
// -> fun List<Todo>.mapToTodoListState() : TodoListState
}
}
What I'm trying to have is a similar syntax to this, with a setState
taking IO
instead of suspending functions:
fun getAllTodo(): IO<List<Todo>>
fun childIO() = setState { getAllTodo().map { TodoListState(it) } }
Any idea where I should start? I've seen that @Jorge Castillo commented on arrow issues in the uniflow github, maybe he'll know what I'm talking about ^^aballano
03/02/2020, 10:35 AMsuspended()/suspendCancellable()
on it, so you would have
suspended fun getAllTodo(): List<Todo>
kluck
03/02/2020, 10:46 AMJorge Castillo
03/02/2020, 10:46 AMfun childIOError() = setState {
onIO {
error("Boom on IO")
}
}
Following docs, in uniflow
all actions can run on a coroutine using a DSL prepared for it, functions like onIO
onMain
, onDefault
just translate to standard withContext(IO)
,withContext(Main)
, withContext(Default)
. Same for launchOnIO
, launchOnMain
, launchOnDefault
if you need to launch it not just switch the dispatcher.
If you look at how the DSL functions are defined, you’ll find this: https://github.com/uniflow-kt/uniflow-kt/blob/5152c197131c7f9d8b3129a37017671c4aea49ae/uniflow-core/src/main/kotlin/io/uniflow/core/threading/Threading.kt
Launch ones are defined over a coroutine scope, like:
fun CoroutineScope.launchOnIO(block: suspend CoroutineScope.() -> Unit) = launch(<http://UniFlowDispatcher.dispatcher.io|UniFlowDispatcher.dispatcher.io>(), block = block)
Those get block
as a suspend function so you can pass an arrow `IO`one there by calling `suspended() or suspendCancellable()`as suggested by Alberto. Alternatively you can write an “overload” that enforces block
to be an arrow IO
instead, so you have both syntax available. Then you can `launch`the IO task inside with the new extension functions to run the passed IO scoped to the receiver scope. (This is just available starting on the snapshot 0.10.5)
For the onXXX
ones are suspend functions you can wrap into IO.effect {}