简体   繁体   中英

list to either of list

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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM