Ifvwm
07/09/2020, 3:03 AMNicolas Lattuada
07/09/2020, 8:34 AMfun t(dto: UpgradeTrigger) {
UpgradeTrigger.run {
title.modify(dto) { it.toUpperCase() }
subtitle.modify(dto) { it.toUpperCase() }
}
}
AdrianRaFo
07/09/2020, 2:11 PMtupled
function for data classes?dimsuz
07/10/2020, 11:15 AMnicopasso
07/10/2020, 11:40 AMmap2
with the two Kleisli instances I’ve created, readNameKCO
and readAgeKCO
. My goal is to create a new Kleisli that generates a Person
instance from a Config
one and then using it with personK.run(config)
. I’m doing something wrong for sure but I don’t quite understand out to build the personK
KleisliMichael Marth
07/14/2020, 8:44 AMList<Option<A>>
into a Option<List<A>>
? So if any if the `Option`s in the original List is None
, the whole return type should be None
.raulraja
07/14/2020, 10:58 AMNicolas Lattuada
07/15/2020, 8:48 AMdata class Bank(val account: ErrorBox<Account>)
data class Account(val balance: Int, val name: String)
@JsonDeserialize(using = ErrorBoxDeserializer::class)
class ErrorBox<T>(var failure: Throwable?, var value: T?)
and in my ErrorBoxDeserializer if the json is valid, I return a value otherwise an error.
How would you do in order to give monad super powers to ErrorBox? it would be great if it could behave just like EitherIan D
07/19/2020, 2:14 AMeither
?Bora Gonul
07/20/2020, 6:02 AMJakub Pi
07/21/2020, 1:16 AMdnowak
07/21/2020, 1:20 PMSagar Suri
07/21/2020, 1:31 PMjulian
07/22/2020, 7:14 PMimplementation "io.arrow-kt:arrow-generic:0.10.5
in the build.gradle
file of an Android project. But this doesn't seem to make Coproduct
available. Is there something else I need to do?simon.vergauwen
07/23/2020, 10:51 AMmarc0der
07/23/2020, 12:18 PMApplicative
and Traverse
. An example of product would be when translating the following function from Scala:
def compose[G[_]](G: Applicative[G]): Applicative[({type f[x] = F[G[x]]})#f] = {
val self = this
new Applicative[({type f[x] = F[G[x]]})#f] {
def unit[A](a: => A) = self.unit(G.unit(a))
override def map2[A,B,C](fga: F[G[A]], fgb: F[G[B]])(f: (A,B) => C) =
self.map2(fga, fgb)(G.map2(_,_)(f))
}
}
The problem here being how to express that type lambda ({type f[x] = F[G[x]]})#f
. The unit
and map2
functions should return types like (F[A], G[A])
, translated to Kotlin that would be Tuple2<Kind<F, A>, Kind<G, A>>
. From what I can tell, this simply isn't possible in Kotlin, but maybe someone else can see a way of achieving this that I just can't see.julian
07/23/2020, 9:46 PMtavish pegram
07/24/2020, 4:33 PMConstrained<T>
as a DSL for domain modeling (inspired by this and other similar talks https://www.youtube.com/watch?v=PLFl95c-IiU▾
data class Natural private constructor(val value: Int) {
companion object {
fun fromInt(v: Int): Either<NaturalFromIntFailure, Natural> =
when (v < 0) {
true -> NaturalFromIntFailure.IntMustBeGTEZero.left()
false -> Natural(v).right()
}
}
}
sealed class NaturalFromIntFailure {
object IntMustBeGTEZero: NaturalFromIntFailure()
}
which is fine I guess, but if people want to get in the habit of using constrained domain types for every type in a domain (as is recommended), this starts to become tedious and starts to lead toward cutting corners on these types.
From reading about dependent types, it would be awesome to do something like
typealias Natural = Constrained<Int><{
when (it < 0) {
true -> NaturalFromIntFailure.IntMustBeGTEZero.left()
false -> Natural(it).right()
}
}>
val x = Natural(-1) // Doesnt compile
val y = Natural.new(-1) // Left(NaturalFromIntFailure.IntMustBeGTEZero)
Alas messing around hasn’t gotten me close to this at all. This is the best I’ve gotten so far which is still a little too verbose , doesn’t have a consistent interface for constrained types, and has some public “private” methods :(
/*
----------------------------------------------------------------------------------------------------
Generic bits
*/
data class Constrained<A> private constructor(val a: A) {
companion object {
fun <A, E>validateNew(a: A, validator: (A) -> Either<E, A>): Either<E, Constrained<A>> =
validator(a).fold(
{ it.left() },
{ Constrained(a).right() }
)
}
}
/*
----------------------------------------------------------------------------------------------------
Consumer Implementation
*/
typealias Natural = Constrained<Int>
sealed class NaturalFromIntFailure {
object IntMustBeGTEZero: NaturalFromIntFailure()
}
fun natural(a: Int) = Natural.validateNew<Int, NaturalFromIntFailure>(a) {
when (it < 0) {
true -> NaturalFromIntFailure.IntMustBeGTEZero.left()
false -> it.right()
}
}
/*
----------------------------------------------------------------------------------------------------
Examples
*/
val a = Natural(-1) // Doesn't compile
val b = natural(1) // Result: Right(Natural(1))
val c = natural(-1) // Result: Left(NaturalFromIntFailure.IntMustBeGTEZero)
Does anyone have any suggestions on if there are any tools available in arrow that could move this closer to the ideal state?PhBastiani
07/25/2020, 12:43 PMAlexander Schell
07/29/2020, 5:22 AMJose Antonio Jimenez
07/29/2020, 3:00 PMval result = Either.right(value).map { suspendFunction(it) }
Jose Antonio Jimenez
07/29/2020, 3:03 PMSatyam Agarwal
07/29/2020, 3:19 PMBig Chungus
07/30/2020, 10:18 AMSatyam Agarwal
07/31/2020, 7:35 AMTaskOf<A>
somehow myself until it gets available in 0.11.0
(i am assuming this) ?Gopal S Akshintala
08/02/2020, 1:06 PMsuspend () -> A
and Kind<F, A>
. Is there any ongoing development to replace or eliminate higher kinds? If yes, can someone please help me by pointing to a doc or with a simple example. Thanks!CLOVIS
08/02/2020, 2:20 PMUnimplemented
Singleton, but that still doesn't look so good.
2. Use inheritance
Create one interface per optional field, and have each provider have its own event implementation that extends the correct interfaces. This could lead to a bit of repetition, though I guess combined with delegation it could look okay.
3. Use WeakHashMap in a typeclass to store the additional information
That doesn't seem very nice as well...
What do you think?Slackbot
08/02/2020, 4:39 PMjulian
08/02/2020, 7:11 PMList
to an arrow.fx
Stream
using the 0.11-snapshot
? IDE completion doesn't appear to offer an appropriate extension that might do this.Satyam Agarwal
08/03/2020, 11:06 AMIO<A>
. I thought of starting with this line :
IO<A>
is just a another way of writing suspend () -> Either<Throwable, A>
is this true ? I grasped this from the PR Simon worked on to bring features from IO to Either using coroutines so that we don’t have to box our types which apparently is costly.
I know IO has its own thread pool, works on fibres and not coroutines, but I was wondering if the above statement could be a layman’s explanation ?Satyam Agarwal
08/03/2020, 11:06 AMIO<A>
. I thought of starting with this line :
IO<A>
is just a another way of writing suspend () -> Either<Throwable, A>
is this true ? I grasped this from the PR Simon worked on to bring features from IO to Either using coroutines so that we don’t have to box our types which apparently is costly.
I know IO has its own thread pool, works on fibres and not coroutines, but I was wondering if the above statement could be a layman’s explanation ?simon.vergauwen
08/03/2020, 12:05 PMIO<A>
~> suspend () -> A
, since suspend
encapsulates Throwable
.
If you try to run suspend () -> A
, you always need to provide a function (Result<A>) -> Unit
in startCoroutine
when constructing a Continiuation<A>
.
Similarly to IO
which exposes a function unsafeRunAsync
which takes a function (Either<Throwable, A>) -> Unit
.
So it's clear these two are the same.
Building IO
is more expensive than using suspend
since IO
is build at runtime, and suspend
is generated by the compiler at compile time. This costs becomes neglectable in heavy concurrent applications with a lot of IO operations, and it becomes more expensive in loops for example.Satyam Agarwal
08/03/2020, 12:07 PMsimon.vergauwen
08/03/2020, 12:07 PMIO
module exposes a set of utilities like Fiber
, Resoure
, Schedule
, dispatchers. and much more to work with IO
.
In the last year I've been working hard on trying to figure out how we could translate all these same principles and patterns from IO
to suspend
without losing any features or capabilities. Which finally landed in the PR you probably saw already.
The same readme can be found here: https://github.com/arrow-kt/arrow-fx/tree/master/arrow-fx-coroutinesSatyam Agarwal
08/03/2020, 12:12 PMsimon.vergauwen
08/03/2020, 12:14 PMSatyam Agarwal
08/03/2020, 12:15 PMfun Application.myModule() : Unit
to suspend fun <http://Application.my|Application.my> module() : Unit { ... myUnsafeIOWrapped.suspendedCancellable() }
Also he asked about blocking and non-blocking.simon.vergauwen
08/03/2020, 12:31 PMThread.sleep
which actually block a thread.
Which is problematic on a pool such as ComputationPool
, IO.dispatchers().default()
or Dispatchers.Default
, since those pools are "work-stealing". Meaning they interleave computational work, which is not possible if an operation is blocking the thread.
(TL;DR Blocking doesn't allow interleaving of tasks)
So a blocking task should be scheduled on an "IO" pool, which creates a new thread per operation. Hence blocking is not a problem, since no interleaving happens on this pool. IOPool
, IO.dispatchers().io()
, <http://Dispatchers.IO|Dispatchers.IO>
, etc.
The part about IO
and suspend
could be argued about perhaps, since on a back-end requests are running in parallel there is always asynchrony involved. What makes both IO
and suspend
so special is that they can wrap a callback
which regular code cannot.
Being able to wrap a callback allows you to jump to a different scheduler, and back, without having to write any of the orchestration around it like you normally would with callbacks.
val result: Result? = ...
runOnComputation { result ->
runOnIO(result) { res2 ->
runOnComputation(res) { res3 ->
finished, return result (???)
result = res3
}
}
}
use result??
compared to
val res = runOnComputation()
val res2 = runOnIO(res)
val res3 runOnComputation(res2)
Where you can implement runComputation
with suspendCoroutine
like you could do with IO.async
.parTraverse
or parTupled
or run them synchronously depending on the config we passed to Ktor.
Similarly you can make functions uncancellable
by wrapping them in uncancellable { }
. Even if they contain cancellable code.Satyam Agarwal
08/03/2020, 12:39 PM