On 30 May 2011 05:05, Christopher Howard <christopher.howard@frigidcode.com> wrote:
Hi. I'm trying to learn Data.ConfigFile. I want to use the function
readfile:
[DESCRIPTION]
readfile :: MonadError CPError m => ConfigParser -> FilePath -> IO (m
ConfigParser)
I understand that this function returns a monad, and I pull the value
out of it with (<-). And I believe this is similar to a "Maybe"
situation where I can do one thing if it provides a syntax error and
another thing if it provides the ConfigParser. But I'm not sure what
this would look like in actual code. Could somebody give me a small,
simple example?
It's understandable that actual usage isn't clear, it wasn't clear to me either when I first encountered it. There are a few ways to use it. It returns an instance of error Monad, so you can either force it into an Either value:
λ> do parser <- readfile emptyCP "../confy.conf"; return (get (forceEither parser) "PATHS" "upload_path") :: IO (Either CPError String)
Right "uploads"
Or you can get it within the monad like everything else:
λ> do parser <- readfile emptyCP "../confy.conf"; return (do config <- parser; get config "PATHS" "upload_path") :: IO (Either CPError String)
Right "uploads"
Because it returns any MonadError instance, and IO is an instance of MonadError, you can skip the double level of monadery:
λ> let getUploads :: IO (Either CPError String); getUploads = runErrorT $ do parser <- liftIO $ readfile emptyCP "../confy.conf"; config <- parser; get config "PATHS" "upload_path" in getUploads
Right "uploads"
Or with join:
λ> :t join
join :: (Monad m) => m (m a) -> m a
λ> let getUploads :: IO (Either CPError String); getUploads = runErrorT $ do cp <- join $ liftIO $ readfile emptyCP "../confy.conf"; get cp "PATHS" "upload_path" in getUploads
Right "uploads"
Control.Applicative also works nicely for this.
instance Applicative (ErrorT CPError IO) where (<*>) = ap; pure = return
λ> let getCfg :: IO (Either CPError (String,String));
getCfg = runErrorT $ do
cp <- join $ liftIO $ readfile emptyCP "../confy.conf";
(,) <$> get cp "PATHS" "upload_path"
<*> get cp "PATHS" "err_log"
in getCfg
Right ("uploads","errors.log")