Using returned EitherT in a haskell program

I am trying to use the "citation-resolve" package in a Haskell project that I am working on, but I am having problems using EitherT in real code. I understand that they are monad transformers, and I think I understand what this means, but I can’t understand how to use them. An example of a toy that represents what I'm trying to do is as follows:

module Main where
import Text.EditDistance
import Text.CSL.Input.Identifier
import Text.CSL.Reference
import Control.Monad.Trans.Class 
import Control.Monad.Trans.Either 

main = do
    putStrLn "Resolving definition"
    let resRef = runEitherT $ resolveEither "doi:10.1145/2500365.2500595"
    case resRef of 
                Left e -> do 
                    putStrLn ("Got error: "++ e)
                Right ref -> do
                    putStrLn ("Added reference to database: "++ (show ref))

Here resolveEitheris of type:

resolveEither :: (HasDatabase s,
                  Control.Monad.IO.Class.MonadIO m,
                  mtl-2.1.3.1:Control.Monad.State.Class.MonadState s m)
                   => String -> EitherT String m Reference

and runEitherT $ resolveEither "ref"has type:

runEitherT $ resolveEither "ref"
   :: (HasDatabase s,
       Control.Monad.IO.Class.MonadIO m,
       mtl-2.1.3.1:Control.Monad.State.Class.MonadState s m)
         => m (Either String Reference)

However, this gives the following error:

Main.hs:10:34:
    No instance for (Control.Monad.IO.Class.MonadIO (Either [Char]))
      arising from a use of ‘resolveEither’
    In the first argument of ‘runEitherT’, namely
      ‘(resolveEither "doi:10.1145/2500365.2500595")’
    In the expression:
      runEitherT (resolveEither "doi:10.1145/2500365.2500595")
    In an equation for ‘resRef’:
        resRef = runEitherT (resolveEither "doi:10.1145/2500365.2500595")

What I do not know how to allow or get around.

Any help would be appreciated, especially pointers to tutorials regarding monad transformers, in terms of use, not implementation.

Edit:

dfeuer Christian, , main :

main = do
    putStrLn "Resolving definition"
    resRef <- runEitherT (resolveEither "doi:10.1145/2500365.2500595")
    case resRef of 
                Left e -> do 
                    putStrLn ("Got error: "++ e)
                Right ref -> do
                    putStrLn ("Added reference to database: "++ (show ref))

, :

No instance for (MonadState s0 IO)
  arising from a use of ‘resolveEither’
In the first argument of ‘runEitherT’, namely
  ‘(resolveEither "doi:10.1145/2500365.2500595")’
In a stmt of a 'do' block:
  resRef <- runEitherT (resolveEither "doi:10.1145/2500365.2500595")
In the expression:
  do { putStrLn "Resolving definition";
       resRef <- runEitherT (resolveEither "doi:10.1145/2500365.2500595");
       case resRef of {
         Left e -> do { ... }
         Right ref -> do { ... } } }

, , , .

+4
3

mtl : . , , transformers. , . (, , , .)

- . :

resolveEither :: (HasDatabase s,
                  MonadIO m,
                  MonadState s m)
                   => String -> EitherT String m Reference

, , s, , . , , : s ( ); m IO , - m StateT s. m, , HasDatabase s => StateT s IO. :

resolveEither' :: HasDatabase s
                  => String -> EitherT String (StateT s IO) Reference
resolveEither' = resolveEither

, , m, . , .

, . IO, IO, "", , <- do. , "" , . ( , "" .)

EitherT runEitherT :: EitherT e m a -> m (Either e a). , m "" EitherT ""? . StateT, runStateT :: StateT s m a -> s -> m (a, s).

(, , , Haddock "" , , "", Haddocks EitherT e m a -> .. .)

, , : s ( s), flip runStateT s . runEitherT $ resolveEither "ref", IO ((Either String Reference), s). (, , , , . flip .) fst, Either, , , , .

, , GHC , . , "" . , , IO - StateT s IO. runStateT runEitherT, , . , .

, : , retEither , , - . , .

, evalStateT, , . ?

, ; hlint .

+1

, , resRef, , , , , .

, :

main = do
    putStrLn "Resolving definition"
    resRef <- runEitherT $ resolveEither "doi:10.1145/2500365.2500595"
    case resRef of 
                Left e -> do
+7

, , , IO (Either String Reference) resolveEither ( resolveDef, ).

, resolveEither

(HasDatabase s, MonadIO m, MonadState s m) => String -> EitherT String m Reference 

(HasDatabase s, MonadIO m, MonadState s m) => String -> m (Either String Reference)

runEitherT . resolveEither. , , . , , Reference resolveEither. :

resolve :: (MonadIO m, MonadState s m, HasDatabase s) => String -> m Reference
resolve = liftM (either (const emptyReference) id) . runEitherT . resolveEither

, .. liftM (either (const emptyReference) id)

, , , , , . , resolve (MonadIO m, MonadState s m, HasDatabase s) => m Reference IO Reference:

resolveDef :: String -> IO Reference
resolveDef url = do
  fn <- getDataFileName "default.db"
  let go = withDatabaseFile fn $ resolve url
  State.evalStateT go (def :: Database)

resolve runEitherT.resolveEither, , IO (Either String Reference):

retEither s = do
    fn <- getDataFileName "default.db"
    let go = withDatabaseFile fn $ ( (runEitherT.resolveEither) s)
    State.evalStateT go (Database Map.empty)

( (def :: Database) (Database Map.empty), def citation-resolve)

:

module Main where
import Text.EditDistance
import Text.CSL.Input.Identifier.Internal  
import Text.CSL.Input.Identifier
import Text.CSL.Reference
import Control.Monad.Trans.Either
import Control.Monad.State as State
import qualified Data.Map.Strict as Map

main = do
    putStrLn "Resolving definition"
    resRef <- retEither "doi:10.1145/2500365.2500595" 
    case resRef of 
                Left e -> putStrLn ("Got error: "++ e)
                Right ref -> putStrLn ("Added reference to database: "++ (show ref))

retEither s = do
    fn <- getDataFileName "default.db"
    let go = withDatabaseFile fn $ ((runEitherT.resolveEither) s)
    State.evalStateT go (Database Map.empty)

Solves the original problem!

However, any pointers to style or ways to simplify the whole process will be greatly appreciated.

+1
source

All Articles