jimn
10/30/2019, 6:21 AMjimn
10/30/2019, 6:41 AMAttila Domokos
11/03/2019, 3:42 AMEither.catch
looks like in this context?
I understand Try { }
is essentially the same, but it still reads better than try/catch
.Devesh Shetty
11/03/2019, 6:11 AMlose
was not added to Decidable? https://hackage.haskell.org/package/contravariant-1.4.1/docs/Data-Functor-Contravariant-Divisible.html#v:lose
https://github.com/arrow-kt/arrow/blob/master/modules/core/arrow-core-data/src/main/kotlin/arrow/typeclasses/Decidable.ktraulraja
11/03/2019, 10:59 AMTry
is deprecated in favor of IO and suspend. Changes like this are coming to other data types to eliminate nesting and improve ergonomics. Once Arrow Meta is available if you choose to use it you can entirely eliminate Either
and all result types in Kotlin of Arbitrary arity. We are working on a plugin for Arrow Meta for Union Types. These union types are Coproducts of arbitrary arity that can be used without nesting:
@optics
@recursion
typealias Result<A> = Union<Error, A> // Union<A, B, ...> synthetic and of arbitrary arity up to 22
val a: Result<Int> = error //ok, no need to error.left()
val b: Result<Int> = 1 // ok, no need to 1.right()
val c: Int? = a // ok because it's an error becomes `null`
val d: Int? = b // ok because it's an Int and stays Int
val e: Result<Int> = "other type" // not ok because not an error or an Int. String is not part of the union
val exhaustiveChecks =
when (a) {
is Error -> TODO()
is Int -> TODO()
}
a.fold({ e: Error -> TODO() }, { n: Int -> TODO() }) //@recursion folds cata and recursion schemes
Result.error.msg.modify(a, String::trim) // @optics DSLs for all union and products
As you can see in the example above there is no notion of left/right constructors and the datatype type args won’t be constrained to 2
.
This also removes the need to use ADTs or sealed classes when your intention is just representing a disjoint union with types you don’t own or can’t modify. Additionally it will include a leaner runtime than Arrow Either or Arrow Coproduct because we can use the type checker in meta at compile time to determine when values are of the union and avoid allocation with unnecessary wrappingtschuchort
11/03/2019, 12:00 PMJannis
11/03/2019, 1:04 PMjulian
11/06/2019, 2:53 PMkluck
11/06/2019, 2:55 PMarrow.fx.internal.Platform$_trampoline$1
really seems Platform
-related after all... Any thoughts?tmg
11/07/2019, 3:02 PMsimon.vergauwen
11/08/2019, 2:50 PMclass ForResult private constructor() { companion object }
typealias ResultOf<A> = arrow.Kind<ForResult, A>
@Suppress("UNCHECKED_CAST", "NOTHING_TO_INLINE")
inline fun <A> ResultOf<A>.fix(): Result<A> = this as Result<A>
Ryan Benasutti
11/08/2019, 4:40 PMpakoito
11/08/2019, 5:17 PMrace
with an IO.sleep
julian
11/08/2019, 6:42 PMMiguel Coleto
11/08/2019, 8:15 PMjulian
11/09/2019, 7:13 PMpakoito
11/10/2019, 7:09 PMpakoito
11/12/2019, 10:55 AMGreg Hibberd
11/13/2019, 9:14 PMfun ListK<Tuple2<String, Int>>.modifyListItem(key: String, amount: Int) = Option.fx {
//Find the item
val index = indexOfFirst { it.a == key }.let { if(it == -1) None else Some(it) }.bind()
//Get the item
val item = get(index)
//Modify
val modified = itemLens.set(item, item.b + amount)
//Create an index
val listIndex = ListK.index<Item>().index(index)
//Replace the item
listIndex.set(this@modifyListItem, modified)
}
pakoito
11/13/2019, 9:36 PMlist.map {
if (it.a == key) {
...
} else {
it
}
}
Stian N
11/14/2019, 10:30 AMpakoito
11/14/2019, 3:12 PMpakoito
11/14/2019, 4:48 PMNikita Smolenskii
11/15/2019, 9:28 AMEither.catch
that forces suspend.
Article provides following code snippet, that somehow correate with current implementation https://github.com/arrow-kt/arrow/blob/b332574a969497dc9f072d52bbb5eea60081a9fe/modules/core/arrow-core-data/src/main/kotlin/arrow/core/Either.kt#L859
suspend fun <A> Either.Companion.catch(f: suspend () -> A): Either<Throwable, A> =
try { f().right() } catch (t: Throwable) { t.left() }
Is there any particular reason to not do instead, that allow catch
function to be suspend
agnostic
inline fun <A> Either.Companion.catch(f: () -> A): Either<Throwable, A> =
try { f().right() } catch (t: Throwable) { t.left() }
with that decalration, both will be possible, with initial declaration - second one only
fun blocking(): Int = 42
suspend fun suspended(): Int = 42
fun main() {
Either.catch { "first: ${blocking()}" }
runBlocking {
Either.catch { "second: ${suspended()}" }
}
}
Why arrow team forces to use coroutines everywhere? Even if it’s not needed.Jannis
11/15/2019, 9:32 AMabendt
11/15/2019, 7:29 PMJannis
11/15/2019, 7:32 PMJohan Basson
11/16/2019, 6:40 AMfun authenticate(
request: AuthenticateRequest,
secretKey: SecretKey,
con: Connection
): Either<ErrorMessage, Token>> = Either.fx {
val (optUser) = getUserByUsername(con, request.username)
val (user) = checkUserExists(optUser)
val (_) = checkPassword(request.password, user)
val (token) = generateToken(user, secretKey)
token
}
In this case secretKey and Connection is dependencies
From what I understand you can use the Reader monad to inject it from the top of the application:
fun authenticate(request: AuthenticateRequest): Reader<Context, Either<ErrorMessage, Token>> {
return ReaderApi.ask<Context>().map { ctx ->
Either.fx {
val (optUser) = getUserByUsername(ctx.sql2o, request.username)
val (user) = checkUserExists(optUser)
val (_) = checkPassword(request.password, user)
val (token) = generateToken(user, ctx.secretKey)
token
}
}
}
But this does not seem to compileJannis
11/17/2019, 7:44 AM