Say there's an l
of type List a
, an e
of type b
which represent an
empty collection and a function add
of type a -> b -> Result x b
.
add
inserts an a
into a b
which is an operation that could fail.
I'd like to apply a fold through l
using add
as the
reducer so that in the end I have a Result with either the b
that contains all
of the a
s in the list or an error.
However, I can't just do List.foldl add e l
because of the signature of add
.
So, what I did is to introduce a new function that unwraps the accumulator to
apply it to add in case it's an Ok
and pass thru if it is an Err
. The code
is below:
reducer : (a -> b -> Result x b) -> a -> Result x b -> Result x b
reducer fn a b =
case b of
Ok c -> fn a c
Err _ -> b
Then I can do List.foldl (reducer add) (Ok e) l
(yay)
It looks like a pretty general function and I started to suspect there must be a more idiomatic way of doing this. Anyone has an idea? Some useful function in the Result module I should be aware of?
@ Elm Slack
take a look at
andThen
from the Result module, see if you can reimplement yourreducer
function with it
Oh, I can do
reducer fn a b = Result.andThen (fn a) b
right? That would allow me to remove one argument from reducer π
@ Elm Slack
yep! or you can just put it into the fold as is
List.foldl (\a b -> Result.andThen (add a) b) (Ok e) l
yeah, that's not too bad. thanks! I was hoping some composition wizardry would allow me to reduce it even more π
@ Elm Slack
lol trying to golf it down further too I get too much enjoyment out of this
Hell, yes! But currently, I'm out of ideas π¬ Any further suggestions are appreciated!