Say I have the following parser function:
validateA :: MyMonad m => TypeA -> TypeB
validateA a = (fmapLT Service $ getB $ bId a) >>= \bResult ->
case bResult of
Nothing -> throwError $ Validation InvalidBId
Just actualB -> return $ B actualB
Where getB
makes an http request to another service
And I wish to map that across an array like so:
validateAs
:: MyMonad m
=> [TypeA]
-> ExceptT Error m [TypeB]
validateAs as = map validateA as
This fails to compile with:
• Couldn't match type ‘[]’ with ‘ExceptT Error m’
Expected type: ExceptT Error m [TypeB]
Actual type: [ExceptT Error m0 TypeB]
• In the expression: map validateA as
In an equation for ‘validateAs’:
validateAs as = map validateA as
• Relevant bindings include
validateAs :: [TypeA]
-> ExceptT Error m [TypeB]
(bound at lib/Flock/Policies/Core/Domain/CancelPolicyV2/Validation.hs:89:1)
|
89 | validateAs as = map validateAs as
How can I map across a list where every call could fail, but then lift the exception out like i want?
Basically how do I go from:
v :: m => A -> ExceptT Error B
and
[A]
to
ExceptT Error [B]
map
has type (a -> b) -> [a] -> [b]
, so you get [ExceptT Error m0 TypeB]
instead of ExceptT Error m [TypeB]
. You can apply sequenceA
to your result:
validateSchedules as = sequenceA $ map validateA as
You can also use function traverse
for this:
validateSchedules as = traverse validateA as
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.