haskell - Can I drop the IO monad on this pure function prettily? -
it quite hard formulate questions titles newbie. please create question search friendly =)
trying write first "real" haskell programme (i.e. not project euler stuff), trying read , parse configuration file nice error messages. far, have this:
import prelude hiding (readfile) import system.filepath (filepath) import system.directory (doesfileexist) import data.aeson import control.monad.except import data.bytestring.lazy (bytestring, readfile) -- type definitions without real educational value here loadconfiguration :: filepath -> exceptt string io configuration loadconfiguration path = filecontent <- readconfigurationfile "c:\\temp\\config.json" configuration <- parseconfiguration filecontent homecoming configuration readconfigurationfile :: filepath -> exceptt string io bytestring readconfigurationfile path = fileexists <- liftio $ doesfileexist path if fileexists filecontent <- liftio $ readfile path homecoming filecontent else throwerror $ "configuration file not found @ " ++ path ++ "." parseconfiguration :: bytestring -> exceptt string io configuration parseconfiguration raw = allow result = eitherdecode raw :: either string configuration case result of left message -> throwerror $ "error parsing configuration file: " ++ message right configuration -> homecoming configuration
this works, io monad in parseconfiguration
not necessary, , should go away. can't drop it, of course, , have not yet found way alter parseconfiguration
pure while keeping prettyness of loadconfiguration
.
what right way write this? if answered in documentation, sorry, did not find it. think reading hackage documentation skill grows rest of haskell skills. =)
p.s.: comments on other style mistakes are, of course, welcome!
if using mtl
, solution given bheklilr in comment one. create parseconfiguration
work on monad implements monaderror
.
if whatever reason not using mtl
, transformers
, need'll function type monad n => except e -> exceptt e n a
"hoists" except
exceptt
on monad.
we can build function using mapexceptt :: (m (either e a) -> n (either e' b)) -> exceptt e m -> exceptt e' n b
, function can alter base of operations monad of exceptt
transformer.
except
exceptt identity
, want disclose identity
, homecoming value in new monad:
hoistexcept :: monad n => except e -> exceptt e n hoistexcept = mapexceptt (return . runidentity)
you define way:
hoistexcept :: monad n => except e -> exceptt e n hoistexcept = exceptt . homecoming . runidentity . runexceptt
haskell monad-transformers
No comments:
Post a Comment