haskell - 返回多个单子
问题描述
我正在阅读 Haskell 中的一些代码,但我无法理解并找到了关于如果函数返回 IO(无论如何)在此之前它可以有其他类型的解释。
这个函数很明显一个 Maybe 返回一个 IO Maybe
也许用户 - > IO(也许用户)
但是来自 scotty 库的下一个返回一个 IO 的 Text 的单子 ActionT 也许???我的心都要炸了!
Maybe User -> ActionT Text IO (Maybe User)
解决方案
Haskell 中的类型构造函数有自己的“种类”系统,您可以将其视为一种类型系统。种类本身没有名字。相反,它们仅表示为星星。所以:
Integer :: *
IO :: * -> *
(实际上种类可以有名字,但这是一个更高级的扩展;暂时不要介意)
Scotty 中的ActionT
类型构造函数接受 3 个参数并且有 kind
ActionT :: * -> (* -> *) -> * -> *
类型有:
错误类型,在本例中为
Text
。一个“内部”monad,它当然必须是一个类型构造函数,它本身带有一个参数。如果您尝试将 a
Text
作为此参数传递,GHC 将报告“种类错误”。在这种情况下,内部单子是IO
.返回类型。
ActionT
是一个 monad,所以在这种情况下,您正在谈论的函数返回 aMaybe User
的方式与您的第一个示例完全相同。
ActionT
是一个 monad 转换器:这意味着它需要一个现有的 monad 并在顶部分层更多功能。这允许程序员将新功能与正在修改的 monad 分开,从而增加模块化。
要获得更多信息,请研究ActionT
. 例如,其中之一是
(Monad m, ScottyError e) => Monad (ActionT e m)
这表示 ifm
是 monad 的实例,并且e
是ScottyError
thenActionT e m
的实例也是 monad 的实例。kind 系统允许以与类型系统用于函数应用程序的方式大致相同的方式进行柯里化,因此Monad
typeclass 知道它的参数必须是 kind * -> *
,看哪,ActionT e m
确实有 kind * -> *
。
推荐阅读
- jestjs - nexus-prisma with jest:运行测试错误
- python - django.core.exceptions.FieldDoesNotExist:原始查询必须包含主键
- kubernetes - kubenetes dns 无法在没有 dns 服务的 pod 上解析
- python - 无法在 AWS Aurora Postgres 可为空的日期时间字段中存储空白、NaT、null、NaN
- cordova - Cordova,Android 10。允许列表 CORS 出错
- reactjs - Material-UI 数据网格 onSortModelChange 导致无限循环
- ios - NSFetchedResultController 委托的顺序 didChange: atSectionIndex:
- model-view-controller - MVC - 如何在 LINQ 查询中引用“this.ID”?
- ios - 如何在 Firebase 中侦听和检查特定元素的值?
- blockchain - 在solidity中返回uint的问题