Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
348 views
in Technique[技术] by (71.8m points)

haskell - list to either of list

Say I have the following parser function:

validateA :: MyMonad m => TypeA -> TypeB
validateA a = (fmapLT Service $ getB $ bId a) >>= Result ->
  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]

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

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

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...