在ExceptT String IO ()
我有一个像这样生成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,但我真的不愿意。
答案 0 :(得分:2)
编辑:糟糕,修复了一个错误。
您的问题似乎存在轻微的不一致,因为您提供的do-block包含的m a
表达式与错误消息中给出的表达式不匹配。
但是,问题最终是这样的:对于某些monad m
,在x <- y
类型的do-block中,每个简单表达式(以及m b
表达式的每个右侧)某些b
必须包含runReaderT ...
类型。因此,通过在ExceptT String IO ()
类型的do-block中使用ExceptT String IO a
表达式,您强制Haskell对某些a
进行Maybe (IO ())
类型检查。但是,它是foo :: ExceptT String IO ()
foo = do Just (putStrLn "won't work") -- has type Maybe (IO ())
undefined
,因此类型检查将失败。
如果您尝试过,则会收到类似的错误:
runReaderT ...
您需要决定如何使foo = do ...
maybe (throwError "reader was Nothing!") liftIO
$ runReaderT ...
undefined
表达式适应周围的do-block。两个合理的选择是:
ExceptT
如果您的maybeReader
为Nothing
或<:p>,会引发foo = do ...
maybe (return ()) liftIO
$ runReaderT ...
undefined
式错误
Nothing
这将... {erm .. $.ajax({
type:'GET',
url:"https://api.xxxxxxxxxxx/v1/" +code+ "?api_key="+API_KEY,
data:{_token: "{{ csrf_token() }}",
},
success: function( msg ) {
}
});
的情况。