Haskell 将类型与IO monad转换器之外的类型对齐
试着用monad transformers来概括我的想法,我可以得到一些玩具的例子,但在这里,我正在努力解决一个稍微现实一些的用例。在此基础上,通过使用Haskell 将类型与IO monad转换器之外的类型对齐,haskell,monads,monad-transformers,Haskell,Monads,Monad Transformers,试着用monad transformers来概括我的想法,我可以得到一些玩具的例子,但在这里,我正在努力解决一个稍微现实一些的用例。在此基础上,通过使用ExceptT的更现实的示例,其中定义了三个助手函数 {-#语言记录通配符#-} --导入以使示例可复制 进口管制.Monad.IO.Class(MonadIO(liftIO)) 进口管制.单子交易.例外 导入符合条件的数据。列表为L 导入数据。文本(Text) 导入符合条件的数据。文本为T 导入系统。随机(随机(randomRIO)) --一些
ExceptT
的更现实的示例,其中定义了三个助手函数
{-#语言记录通配符#-}
--导入以使示例可复制
进口管制.Monad.IO.Class(MonadIO(liftIO))
进口管制.单子交易.例外
导入符合条件的数据。列表为L
导入数据。文本(Text)
导入符合条件的数据。文本为T
导入系统。随机(随机(randomRIO))
--一些类型声明,使示例更容易理解
newtype Error=导出显示的错误文本
newtype SQLQuery=SQLQuery文本派生显示
newtype Name=Name{unName::Text}派生显示
数据WithVersion=WithVersion{vName::Name,vVersion::Int}
--|对于每个名称,从外部数据存储中检索相应的版本
retrieveVersions::[Name]->异常错误IO[WithVersion]
retrieveVersions name=do
doerrorsqlquery
mkquerywithversions=
SQLQuery$mconcat$L.interspose“\n”$(\WithVersion{..}->
未命名vName:“T.pack(显示vVersion)
)带版本
--|查询外部SQL数据库并以文本形式返回结果
queryDB::SQLQuery->ExceptT错误IO文本
queryDB q=do
doError仔细考虑各种do
块使用的monad。让我们首先看一下您对检索值的第一个定义:
retrieveValues::[Name]->异常错误IO文本
retrieveValues name=do
结果是纯结果
此函数位于ExceptT Error IO
monad中,这意味着顶部do
块中的每个语句都需要位于该monad中。但是,您的第一条语句eitherResult ExceptT Error IO Text
retrieveValues name=do
RunExcept$do
使用版本时,请仔细考虑各种块使用的monad。让我们首先看一下您对检索值的第一个定义:
retrieveValues::[Name]->异常错误IO文本
retrieveValues name=do
结果是纯结果
此函数位于ExceptT Error IO
monad中,这意味着顶部do
块中的每个语句都需要位于该monad中。但是,您的第一条语句eitherResult ExceptT Error IO Text
retrieveValues name=do
RunExcept$do
对于版本,您根本不需要runExceptT
。retrieveValues
函数声明的返回类型是一个异常
,而不是一个IO(或错误文本)
现在我感到很尴尬:)@4castle感谢这个(非常明显的)答案。这可能是由于这个例子和我试图构建的现实世界的更大背景之间的混淆造成的。现在这一切都很好。你根本不需要runExceptT
。retrieveValues
函数声明的返回类型是一个异常
,而不是一个IO(或错误文本)
现在我感到很尴尬:)@4castle感谢这个(非常明显的)答案。这可能是由于这个例子和我试图构建的现实世界的更大背景之间的混淆造成的。现在这一切都很好。
• Couldn't match type ‘IO’ with ‘ExceptT Error IO’
Expected type: ExceptT Error IO (Either Error Text)
Actual type: IO (Either Error Text)
• In a stmt of a 'do' block:
eitherResult <- runExceptT
$ do withVersions <- retrieveVersions names
let query = mkQuery withVersions
queryDB query