ReaderT Monad Transformer 中 * 的目的是什么?

6
我正在查看有关Reader MonadReaderT文档

相关定义如下:

newtype ReaderT k r m a :: forall k. * -> (k -> *) -> k -> *
type Reader r = ReaderT * r Identity

我不理解定义中的*是什么意思。特别是我正在尝试从以IO为基础monad和对r值有类约束的ReaderT派生出一个新的monad。

我不确定为什么ReaderT有第四个输入(k),以及当它在那个位置放置一个*时,Reader会如何处理该值。


7
请注意,ReaderT 的源代码是 newtype ReaderT r m a = ReaderT { runReaderT :: r -> m a }。文档中生成的 k 只是 Haddock 强调 ReaderT 的多态性(在定义它的模块中启用了 -XPolyKinds)。 - Alec
2
我正在尝试从以IO为基础monad和对r值的类约束的ReaderT中派生出一个新的monad。虽然这可能会引起更多问题,但我不认为这会受到ReaderT的polykinded定义的阻碍。正如@Alec所说,k参数是haddock的产物 - 实际上,它完全是隐含的,你可以假装ReaderT :: (* -> *) -> * -> *(因为它确实具有该类型)。 - user2407038
我希望有一天Haddock能够将类型参数用花括号或类似的方式表示出来(或者可能用“@”作前缀)。将类型参数和种类参数放在一起阅读可能会让人感到困惑(虽然TypeInType可能会使事情变得更加模糊)。 - David Young
1
@JohnF.Miller 我可以在这里看到构造函数和字段名称:http://hackage.haskell.org/package/mtl-2.2.1/docs/Control-Monad-Reader.html#t:ReaderT。你在哪里发现它被省略了?(如果你在那里没有看到它,那么你应该看一下 - 我只能猜测你的浏览器出了些问题)。 - user2407038
@JohnF.Miller 我建议你直接询问现有的回答者修改他的答案以提到 Haddock。我认为大多数遇到这个问题的人都会看到我的评论。 - Alec
显示剩余2条评论
1个回答

5
* 是具有值的类型,它表示像 IntList Int 等等这些东西。而 forall k 的意思是 k 不一定是那种类型,它代表任何类型的种类,视为简单的静态事物,可以声明和操作,但不一定与运行时值相关联。这种情况的一个例子是当您想要用额外的信息“装饰”其他类型时:绣花类型没有理由附加任何类型的值,它是“纯粹”的信息,对于某些带值的绣花类型(通常有值)。
更简单地说,在 Reader 中,所有内容都被专门化为 *,而 m 则被专门化为 Identity monad。这就是您想要使用 IO monad 的地方。
至于约束条件,最好不要在类型本身中指定。在使用时,当您使用特定于类型类的方法时,它将被动态添加进来。确实,没有理由写出不使用方法的表达式应该被要求其调用者提供它。(除非您有很好的理由去推导其他实例,例如 Dict,在其中您捕获了一个类型类见证作为一个 GADT 的运行时值,但那可能不是您想要做的事情)。

你是正确的。约束现在属于一个实例声明,而不是单子定义。 - John F. Miller

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接