jean
12/20/2023, 9:06 AMeither
block than using shift
? this is my case
either {
val data = dao.getData(externalReference) ?: shift(Error.NoData)
...
}
I could make a new function that return a Either<Error.NoData, Data>
and then use bind
but then I need to pass parameters along and all and I end up with 5 or 6 lines for just 1 line that is actually interesting. It would be nice to have a or
functions or something like that as an extensionCLOVIS
12/20/2023, 9:18 AMswitch
.jean
12/20/2023, 9:19 AMshift
not switch
in the questionCLOVIS
12/20/2023, 9:21 AMval data = dao.getData(externalReference)
ensureNotNull(data) { Error.NoData }
Also, shift
is called raise
now 🙂jean
12/20/2023, 9:22 AMCLOVIS
12/20/2023, 9:35 AMCLOVIS
12/20/2023, 9:35 AMCLOVIS
12/20/2023, 9:36 AMrecover
and mapErrors
now, I don't know how we ever wrote code without them lolYoussef Shoaib [MOD]
12/20/2023, 3:26 PMcontext(Raise<Error.NoData>)
fun Dao.getData(externalReference: ExternalReference) = getDataSomehow(externalReference) ?: raise(Error.NoData)
simon.vergauwen
12/20/2023, 5:10 PMensureNotNull
over ?:
, even when using context(Raise<Error.NoData>)
. It's one of the few places I prefer a DSL function instead of Kotlin language feature, but I find it so similar to requireNotNull
that it feels idiomatic to me.Youssef Shoaib [MOD]
12/20/2023, 5:35 PMSingletonRaise
is being worked out right now, but when that's done, you'll be able to declare a block that allows you to do ensureNotNull(data)
and data.bind()
with the fallback value pre-decided. That'd allow you to call many functions that can fail where failing doesn't have a meaningful value. I think when that design is fledged out (it won't be before Arrow 2 because there's breaking changes involved) and accepted, this use case would get much simplersimon.vergauwen
12/21/2023, 7:21 AMYoussef Shoaib [MOD]
12/21/2023, 9:16 AMSingletonRaise
that is intended to unify the APIs of nullable
, option
, and ignoreErrors
. Its usage here would be similar to withError
, but introducing a SingletonRaise
instance instead that has a no-arg raise
method alongside ensureNotNull(foo)
and Option.bind()
and any other "methods that fail with a meaningless value"
It's very much in the works, but it'd look something like:
either {
withSingletonError({ Error.NoData }) {
// Can bind nullable inside:
val data = dao.getData(...).bind()
// Can write ensure with no error specified:
ensure(data is Bar)
data.barMethod() // smart casts should work accordingly I think
}
}
If you want, it's practically option(block).getOrElse { raise(error()) }
I realise while writing this that this particular method isn't in the PR just yet 😅. It's a rather natural extension though, and amounts to perhaps 2-3 linesjean
12/21/2023, 10:57 AMError
. I guess withSingletonError
wouldn’t fit thereYoussef Shoaib [MOD]
12/21/2023, 11:40 AMbind()
nullable things and ensure
without an error specified, and at the same time you can raise any other errors you want, and the either
would deal with them. Maybe you'd need to massage the compiler by specifying the either
type params, but otherwise everything works fine I believe.