首页 > 解决方案 > 返回多个单子

问题描述

我正在阅读 Haskell 中的一些代码,但我无法理解并找到了关于如果函数返回 IO(无论如何)在此之前它可以有其他类型的解释。

这个函数很明显一个 Maybe 返回一个 IO Maybe

也许用户 - > IO(也许用户)

但是来自 scotty 库的下一个返回一个 IO 的 Text 的单子 ActionT 也许???我的心都要炸了!

Maybe User -> ActionT Text IO (Maybe User)

标签: haskell

解决方案


Haskell 中的类型构造函数有自己的“种类”系统,您可以将其视为一种类型系统。种类本身没有名字。相反,它们仅表示为星星。所以:

Integer :: *
IO :: * -> *

(实际上种类可以有名字,但这是一个更高级的扩展;暂时不要介意)

Scotty 中的ActionT类型构造函数接受 3 个参数并且有 kind

ActionT :: * -> (* -> *) -> * -> *

类型有:

  • 错误类型,在本例中为Text

  • 一个“内部”monad,它当然必须是一个类型构造函数,它本身带有一个参数。如果您尝试将 aText作为此参数传递,GHC 将报告“种类错误”。在这种情况下,内部单子是IO.

  • 返回类型。ActionT是一个 monad,所以在这种情况下,您正在谈论的函数返回 aMaybe User的方式与您的第一个示例完全相同。

ActionT是一个 monad 转换器:这意味着它需要一个现有的 monad 并在顶部分层更多功能。这允许程序员将新功能与正在修改的 monad 分开,从而增加模块化。

要获得更多信息,请研究ActionT. 例如,其中之一是

 (Monad m, ScottyError e) => Monad (ActionT e m)

这表示 ifm是 monad 的实例,并且eScottyErrorthenActionT e m的实例也是 monad 的实例。kind 系统允许以与类型系统用于函数应用程序的方式大致相同的方式进行柯里化,因此Monadtypeclass 知道它的参数必须是 kind * -> *,看哪,ActionT e m确实有 kind * -> *


推荐阅读