Hmmm, it looks like you’re trying to sequence error-throwing actions in the same do
block. This is the usual situation where you may want to do everything in ExceptT
instead.
i.e. If you think that instead of this following example (…of reading a file, parsing to JSON, then decoding that json to a domain type) where all of the staircasing happens in Effect
(and where we case match on each potential error on the spot)…
main :: -> Effect Unit
main = do
eResultString <- try (readTextFile UTF8 "IDONTEXIST.json")
case eResultString of
Left error ->
Console.log $ "Couldn't open IDONTEXIST.json. Error was: " <> show error
Right resultString -> do
case Argo.jsonParser resultString of
Left stringError -> Console.error $ "Error parsing string to JSON: " <> stringError
Right json -> do
let codec = CAR.object "Person" { name: CA.string, age: CA.number }
case CA.decode codec json of
Left jsonErr -> Console.error $ CA.printJsonDecodeError jsonErr
Right person -> do
Console.log "'IDONTEXIST.json' has been read/parsed/decoded successfully to the following Person: \n"
logString $ show person
…that you might prefer the following ‘ExceptT’-based style instead that…
-- | ... handles the error case pattern matching explicitly just once here:
main :: Effect Unit
main =
runExceptT exceptExample >>= case _ of
Left myError ->
Console.error $ renderMyError myError
Right person -> do
Console.log $ "Successfully decoded a person from IDONTEXIST.json: \n"
Console.logShow person
-- | And that gets a nice cleaner 'do'-block for the 3 actions being
-- | sequenced than the staircasing example:
-- | (i.e. where it is more imperative-like, in that you 1) read in a string, 2)
-- | parse the string to JSON, then 3) decode the JSON to a domain type:
exceptExample :: ExceptT MyError Effect Person
exceptExample = do
resultString <- liftEitherWith MkFileError $ try (readTextFile UTF8 "IDONTEXIST.json")
resultJson <- hoistEitherWith MkParseError $ Argo.jsonParser resultString
resultPerson <- hoistEitherWith MkDecodeError $ CA.decode personCodec resultJson
pure resultPerson
…then have I got the Gist for you 
https://try.purescript.org/?gist=06ac4bd0908fc7a748884952efcddece
edit: Cleaned things up a bit as the comments were originally all over the shop and didn’t match what the example had evolved into. I’ve done some further evolving too, but hopefully everything aligns properly now.