relude-reason-react icon indicating copy to clipboard operation
relude-reason-react copied to clipboard

Change the IO-based actions to require an `IO.t(action, Void.t)`

Open andywhite37 opened this issue 4 years ago • 3 comments

@mlms13 pointed out that sometimes you do IO-based updates in a reducer (UpdatedWithIO, etc.), but the IO can't fail (has an error type of Void.t). The framework is requiring you to return an IO.t(action, action) right now, and I did that mainly for convenience, but it probably makes sense to change the expected type to IO.t(action, Void.t) to indicate that you have handled the errors (by changing them to a successful action), and to also allow for IO actions that can't fail.

This would be a breaking change, and would require users to update their code everywhere, but the change should be very simple to make. I.e. using IO.handleError.

andywhite37 avatar Feb 06 '20 16:02 andywhite37

Yeah, this came up when I was working on random generators, which produce values inside IO, but the effect can't fail. On the other hand mapError(absurd) made me feel really cool. :)

I think the IO.t(action, action) came about before handleError was a thing, but with that function being just as easy to use as mapError now, I think it makes sense to require a void error channel.

mlms13 avatar Feb 06 '20 17:02 mlms13

I know I've mostly used bimap to convert the IO values to actions, so we could add a helper function to IO like mapHandleError which lets' you map and handleError at the same time. This way, people who were using bimap could fix their code by just changing that function name.

let mapHandleError: 'a 'e 'b. ('a => 'b, 'e => 'b, IO.t('a, 'e)) => IO.t('b, Void.t)

Name suggestions welcome... mapHandleError/mapHandle?... maybe ZIO has a function like this we can copy.

The same function would also make sense for other bifunctors like Result and Validation, so it could live in BifunctorExtensions but it gets a little tricky b/c this implies success/fail semantics, but bifunctor doesn't necessarily impose those same semantics. I would probably just put the function in each of the modules and not try to make it an extension.

andywhite37 avatar Feb 06 '20 18:02 andywhite37

mapHandleError function was added in relude v0.54.0

andywhite37 avatar Feb 07 '20 20:02 andywhite37