Saturday, 15 January 2011

haskell - Can I drop the IO monad on this pure function prettily? -



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