I want to apply a function f to a list of values, however function f might randomly fail (it is in effect making a call out to a service in the cloud).
I thought I’d want to use something like map, but I want to apply the function to all elements in the list and afterwards, I want to know which ones failed and which were successful.
Currently I am wrapping the response objects of the function f with an error pair which I could then effectively unzip afterwards
i.e. something like
g : (a->b) -> a -> [ b, errorBoolean]
f : a-> b
and then to run the code … map g (xs)
Is there a better way to do this? The other alternative approach was to iterate over the values in the array and then return a pair of arrays, one which listed the successful values and one which listed the failures. To me, this seems to be something that ought to be fairly common. Alternatively I could return some special value. What’s the best practice in dealing with this??
If
fis making a call out to the cloud, thanfis undoubtedly using some monad, probably theIOmonad or a monad derived from theIOmonad. There are monadic versions ofmap. Here is what you would typically do, as a first attempt:This has the (possibly) undesirable property that
gwill fail, returning no values, if any call toffails. We fix that by making it sofreturns either an answer or an error message.If you want all of the errors to be returned together, and all of the successes clumped together, you can use the
leftsandrightsfunctions fromData.Either.If you don’t need the error messages, just use
Maybe Binstead ofEither Error B.The
Eitherdata type is the most common way to represent a value which can either result in an error or a correct value. Errors use theLeftconstructor, correct values use theRightconstructor. As a bonus, “right” also means “correct” in English, but the reason that the correct value uses theRightconstructor is actually deeper (because this means we can create a functor out of the Either type which modifies correct results, which is not possible over theLeftconstructor).