【发布时间】:2017-04-14 09:13:01
【问题描述】:
在 ExceptT String IO () 的 do 块内
我有一个生成 ReaderT 的函数,如下所示:
type UDCEnv = (AWS.Env, Bool)
uploadVersionFilesToCaches :: S3.BucketName
-> FilePath
-> [GitRepoNameAndVersion]
-> ReaderT UDCEnv IO ()
我恰好有一个Maybe FilePath,所以我这样创建了我的 ReaderT:
let maybeReader :: Maybe (ReaderT UDCEnv IO ()) =
uploadVersionFilesToCaches s3BucketName <$> maybeFilePath <*> Just gitRepoNamesAndVersions
我什至可以像这样运行 ReaderT:
let maybeIO :: Maybe (IO ()) =
runReaderT <$> maybeReader <*> Just (env, shouldIgnoreLocalCache, verbose)
只要我使用let 表达式,一切正常。只要我在上面的表达式中删除let 以实际尝试评估表达式 Applicative 获取类型为ExceptT String IO FilePath 而不是Maybe
我省略的部分用...标记:
f :: ... -> ExceptT String IO ()
f ... = do
...
runReaderT <$> maybeReader <*> Just (env, shouldIgnoreLocalCache, verbose) -- Error here
undefined
生产
Couldn't match type ‘IO ()’ with ‘()’
Expected type: ReaderT UDCEnv IO () -> UDCEnv -> ()
Actual type: ReaderT UDCEnv IO () -> UDCEnv -> IO ()
In the first argument of ‘(<$>)’, namely ‘runReaderT’
In the first argument of ‘(<*>)’, namely
‘runReaderT
<$>
(uploadVersionFilesToCaches s3BucketName <$> maybeFilePath
<*> Just gitRepoNamesAndVersions)’
/Users/blender/Code/Personal/Haskell/Rome-Public/src/Lib.hs: 82, 73
Couldn't match type ‘Maybe’ with ‘ExceptT String IO’
Expected type: ExceptT String IO FilePath
Actual type: Maybe FilePath
In the second argument of ‘(<$>)’, namely ‘maybeFilePath’
In the first argument of ‘(<*>)’, namely
‘uploadVersionFilesToCaches s3BucketName <$> maybeFilePath’
我认为第一个错误是因为我在某处遗漏了一些 liftIO。
但是我不知道如何处理被误解的 Applicative。
我当然可以对 Maybe 进行案例分析,而不是使用 Applicative,但我真的不想这样做。
【问题讨论】:
-
从错误来看,你缺少的是
return,而不是liftIO。 -
@arrowd 很可能,但不幸的是,这对我的应用问题没有帮助。也许这不是开始的正确方法?
-
您能否包含
runReaderT ...表达式实际出现的代码?最有可能的是,它在 do-block 中的使用方式是 Haskell 试图将其键入为ExceptT String IO ()而不是Maybe (IO ())。这最终将解释这两个错误,因为Maybe不是ExceptT String IO,而()不是IO ()。它可能就像添加一个标准的 Maybe-to-ExceptT 接口一样简单。 -
@K.A.Buhr 它只是出现在
do块的中间ExceptT String IO ()查看编辑
标签: haskell monads monad-transformers applicative maybe