It’s a smallish change to the code, where I get rid of a lot of the annoying
casting code to go Either -> EitherT, and instead just write everything in
The biggest change was the type signature of my failure code. See how I add
the Monad constraint, and update the return value to be EitherT wrapped around
whatever monad you have.
What’s cool about this is that it’ll work right for both IO, and every other
monad we want to embed this eitherFailure code into. Which means that as a
hypothetical application’s monad transformer stack builds up, it would be easy
to just plug this code in and go.
importControl.ErrorimportControl.Monad.Trans-- A type for my example functions to pass or fail on.dataFlag=Pass|Errormain::IO()main=doputStrLn"Starting to do work:"result<-runEitherT$dolift$putStrLn"Give me the first input please:"initialText<-liftgetLinex<-eitherFailureErrorinitialTextlift$putStrLn"Give me the second input please:"secondText<-liftgetLiney<-eitherFailurePass(secondText++x)noteT("Failed the Maybe: "++y)$maybeFailurePassycaseresultofLeftval->putStrLn$"Work Result: Failed\n "++valRightval->putStrLn$"Work Result: Passed\n "++valputStrLn"Ok, finished. Have a nice day"eitherFailure::Monadm=>Flag->String->EitherTStringmStringeitherFailurePassval=right$"-> Passed "++valeitherFailureErrorval=left$"-> Failed "++valmaybeFailure::Monadm=>Flag->String->MaybeTmStringmaybeFailurePassval=just$"-> Passed maybe "++valmaybeFailureError_=nothing