【发布时间】:2014-11-24 11:30:11
【问题描述】:
我正在尝试在我正在处理的 Haskell 项目中使用“引文解析”包,但在实际代码中使用 EitherT 时遇到了麻烦。我知道它们是 monad 转换器,我想我理解这意味着什么,但是我似乎无法真正弄清楚如何使用它们。代表我正在尝试做的玩具示例如下:
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")
我不知道如何解决或解决。
任何帮助都将不胜感激,尤其是从使用角度而非实现角度处理 monad 转换器的教程的指针。
编辑:
为了反映 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 { ... } } }
我正在编辑我的问题并发表评论,因为这里的代码格式比在评论中要容易得多。
【问题讨论】:
-
改写 dfeuer 的回答,您可以尝试用
resRef <- runEitherT {-...-}替换let resRef = runEitherT {-...-}吗?如果这样解决了它并且您不理解,我可以尝试解释。 -
正如我的编辑所反映的,我已经尝试过了,但仍然出现类型错误。我认为我知道为什么它应该起作用,因为它“解开”了一层monad(即IO),对吗?
标签: haskell monads monad-transformers either io-monad