When looking at arrows documentation about functional error handling one of the reason listed to avoid throwing exceptions is performance cost (referencing The hidden performance costs of instantiating Throwables)
So it is suggested to model errors/failures as an Effect
.
When building an Effect
to interrupt a computation the shift()
method should be used (and under the hood it is also what is used to "unwrap" the effects through the bind()
method).
Looking at the shift()
method implementation seems that its magic is done...throwing an exception, meaning that not only exceptions are created when we want to signal an error, but also to "unwrap" any missing Option
, Left
instance of an Either
and all the other effect types exposed by the library.
What I'm not getting is if there's some optimization done to avoid the issues with "the hidden performance costs of instantiating Throwables", or in the end they are not a real problem?