我正在进行一个Haskell项目,尝试使用“citation-resolve”包,但是在实际代码中使用EitherT的过程中遇到了麻烦。我知道它们是Monad Transformer,也理解了这意味着什么,但似乎无法真正弄清如何使用它们。下面是一个玩具示例,代表我想要做的事情:
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))
在这里,
resolveEither
的类型为: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
runEitherT $ resolveEither "ref"
的类型为:
并且
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)
然而,这会导致以下错误:
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")
我不知道如何解决或绕过这个问题。
任何帮助都将不胜感激,尤其是指向从使用角度而非实现角度处理单子变换器的教程的指针。
编辑:
为了反映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 { ... } } }
我正在编辑我的问题并添加评论,因为这里的代码格式化要比评论中容易得多。请注意,我保留了HTML标签。
let resRef = runEitherT {-...-}
替换为resRef <- runEitherT {-...-}
。如果这样修复了问题而你还是不理解的话,我可以尝试解释一下。 - Christian Conkle