kyleg
12/19/2019, 5:32 PMIO { File("/path/to…").walk()) }
and apply IO transforms to the sequence to end up with an IO<Sequence<IO<Foo>>>
and then use flatMap
and sequence
to transform it to IO<Sequence<Foo>>
. When I unsafeRunSync
the result, I get a StackOverflowError
, presumably from the part where I “lift” the nested IO out of the Sequence (has to iterate over all the elements in the sequence I think).
Given that you’re ideally going to have a single place at the “edge” to run the IO, is there a better way I should structure it? Assume I’m starting with IO<Sequence<IO<Foo>>>
and can do whatever to it. Is myIO.unsafeRunSync().forEach { it.unsafeRunSync() }
the way I should go about doing it at the edge? Basically run the top-level IO to get the Sequence
and then start taking values, whcih are themselves IO
, and run them?
Here is a simplified version of what I have now:
fun buildFoo(file: File): IO<String> = IO { "test" }
val program: IO<Sequence<File>> = IO { File("/Users/kylegoetz/Desktop").walk() }
val transformedProgram: IO<Sequence<IO<String>>> = program.map {
it.map {
buildFoo(it)
}
}
val noNestedIO: IO<Sequence<String>> = transformedProgram.flatMap {
it.filterNotNull().k().sequence(IO.applicative()).fix()
}
noNestedIO.unsafeRunSync() // StackOverflowError
Jannis
12/19/2019, 7:17 PMap
(it's actually solution to many many more problems 🙈 ) with that we would instantly return from traverse
and execute/bind the IO
as we gokyleg
12/19/2019, 7:24 PMjimn
12/19/2019, 8:04 PMoperator fun <A, B, C> Function1<A, B>.times(r: Function1<B, C>): (A) -> C = { x: A -> x.let(this).let(r) }
demonstrated below with the _***_'s
val bb2ba: (ByteBuffer) -> ByteArray = { bb: ByteBuffer -> ByteArray(bb.remaining()).also { bb[it] } }
val btoa: (ByteArray) -> String = { ba: ByteArray -> String(ba, Charsets.UTF_8) }
val trim: (String)->String = String::trim
enum class TypeMemento(val bytes: Int?, val read: readfn, val write: writefn) {
txtInt(4, (bb2ba * btoa * trim * String::toInt), { a: ByteBuffer, b: Int? -> a.putInt(b ?: 0) } as writefn),
Sagar Suri
12/20/2019, 9:54 AMraulraja
12/20/2019, 5:23 PMstojan
12/22/2019, 1:15 PMarrow/core/Continuation
java.lang.NoClassDefFoundError: arrow/core/Continuation
in testsMichael Marth
12/22/2019, 5:08 PMPromise
to mimic the view model lifecycle callback (as described at the end of the post):
val endPromise: Promise<ForIO, Unit> = Promise.unsafeUncancelable(IO.async()).fix()
simply does not compile.
Same for
endPromise.complete(Unit).unsafeRunAsync { }
accordigly.
fix()
/ unsafeRunAsync
are simply not availble on the Promise
instance. Any ideas?Fudge
12/22/2019, 8:13 PMOption<>
types over Nullable?
types other than the syntactic difference?pakoito
12/23/2019, 3:10 PMtypealias Bla = suspend (In) -> Out
stojan
12/23/2019, 6:40 PMIO
fails?Egor Trutenko
12/24/2019, 1:09 PMkyleg
12/24/2019, 5:47 PMImageIO.read
here. I understand it probably wants me to put this in a suspend fn and it’s just a linting thing. But since it’s in an IO.fx
and has !bind
wrapped around it, I should ignore this linting warning, right? That’s part of the point of IO and !effect, right?
fun imageReader(file: File): IO<Either<Throwable, ByteArray>> = IO.fx {
with(!effect { ImageIO.read(file) }) {
val argbArray = getRGB(0,0, width, height,null,0, width)
val buffer = java.nio.ByteBuffer.allocate(4*argbArray.size)
argbArray.forEach { buffer.putInt(it) }
buffer.flip()
buffer.array().slice(0 until argbArray.size*4).toByteArray()
}
}.attempt()
kyleg
12/24/2019, 5:49 PMlaunch(<http://Dispatchers.IO|Dispatchers.IO>)
or something? (This is a Kotlin command line program I’m working on)julian
12/25/2019, 4:10 PMstojan
12/26/2019, 11:23 AMTim Fennis
12/27/2019, 3:50 PMursus
12/29/2019, 3:17 AMMichael Marth
12/30/2019, 3:05 PMIO
actions all together with one call to unsafeRunSync
. I know in Haskell there is sequence
- is there a similar construct in Arrow?mattmoore
01/01/2020, 3:04 AMmattmoore
01/01/2020, 3:23 AMRazvan
01/02/2020, 2:48 PMAdam Daniel
01/02/2020, 8:57 PMobject BusinessError
object User
object UserProfile
suspend fun findUserByName(name : String) : Either<BusinessError, User> = TODO()
suspend fun getUserProfile(user: User) : Either<BusinessError, UserProfile> = TODO()
suspend fun getUserProfile(name : String) : Either<BusinessError, UserProfile> = Either.fx {
val user = findUserByName(name).bind()
getUserProfile(user).bind()
}
Christian Maus
01/04/2020, 1:43 PMimport arrow.core.Either
import arrow.core.ForEither
import arrow.core.Option
import arrow.core.Try
import arrow.fx.ForIO
import <http://arrow.fx.IO|arrow.fx.IO>
import <http://arrow.fx.extensions.io|arrow.fx.extensions.io>.applicative.applicative
import arrow.mtl.EitherT
import arrow.mtl.OptionT
typealias IOResult = EitherT<ForIO, Throwable, OptionT<ForEither, Int>>
val doesNotWork = IOResult.fromEither(IO.applicative(), Either.catch { Option.just(3) })
val doesWork = IOResult.fromEither(IO.applicative(), Try { Option.just(3)}.toEither())
abendt
01/04/2020, 2:35 PMsuspend
function should not use blocking operations. How is this in the context of arrow-fx and IO
? Is this a requirement here too or is suspend
only used as a marker to tag functions for having sideeffects?jimn
01/06/2020, 2:28 PM/** left identity */
object `⟳` {
operator fun <T> invoke(t: T) = { t: T -> t }
}
/** left identity */
val <T> T.`⟳` get() = `⟳` ( this)
/**right identity*/
val <T> T.`⟲` get() = { this }
rcd27
01/07/2020, 7:26 AMarrow-kt
connects people who loves Functional Programming and I really wish to work with Arrow
on project or on back-end Scala.Scott Christopher
01/07/2020, 9:11 AMinterface Functor<F, A> {
fun <B> Kind<F, A>.map(f: (A) -> B): Kind<F, B>
}
The reason I ask is that I went to update the Profunctor
interface to extend Functor
and provide the default implementation for map
using rmap
, though the only way I could make the types line up was to update Functor<F>
to Functor<Kind<F, A>, B>
like so:
interface Profunctor<F, A, B> : Functor<Kind<F, A>, B> {
fun <C, D> Kind2<F, A, B>.dimap(fl: (C) -> A, fr: (B) -> D): Kind2<F, C, D>
fun <C> Kind2<F, A, B>.lmap(f: (C) -> A): Kind2<F, C, B> = dimap(f, ::identity)
fun <C> Kind2<F, A, B>.rmap(f: (B) -> C): Kind2<F, A, C> = dimap(::identity, f)
override fun <C> Kind<Kind<F, A>, B>.map(f: (B) -> C): Kind<Kind<F, A>, C> = rmap(f)
}
kyleg
01/07/2020, 8:11 PMKind<F, A>
is so helpful compared to F<A>
(i.e. and e.g., not hard-coding that your return type is Option<A>
)? I’m hoping there’s some blog out there showing a real-world reason someone chose to do this and how it benefited them.
Is this just so you don’t have to refactor your function’s signatures from an Either<Throwable, A>
into an Option<A>
if you change your mind halfway through development, or is there something greater out there?
It seems like tutorials are implying a connection to something like an interface
in OOP (being able to write to a more generic “contract”), but I haven’t been working with FP long enough to grok the real-world benefits. Thanks.Frank
01/08/2020, 4:55 PMList<A>
and a function A -> Option<B>
, is there an operator, or series of operators, that would iterate over the list, applying the function, and return the first Option<B>
that is a Some<B>
, and if none do, returns None
? Similar to a findFirst
but runs a computationFrank
01/08/2020, 4:55 PMList<A>
and a function A -> Option<B>
, is there an operator, or series of operators, that would iterate over the list, applying the function, and return the first Option<B>
that is a Some<B>
, and if none do, returns None
? Similar to a findFirst
but runs a computationJannis
01/08/2020, 5:07 PMfilterMap(f).firstOption()
using filterMap
from FunctorFilter
and firstOption
from Foldable
. (If you do the same with asSequence().filterMap(f).firstOption()
it'll also be lazy ^^).
When this pr (https://github.com/arrow-kt/arrow/pull/1897) is merged you can also do map(f).asum(Option.alternative(), ListK.foldable())
asum
basically tries every element and short-circuits on success (which is similar to traverse
which short-circuits on failure).
I'd suggest doing the asSequence().filterMap(f).firstOption()
because it won't apply the function unnecessarily and because it is available now ^^.Frank
01/08/2020, 5:44 PM