【问题标题】:MaybeT's m in Type SignatureMaybeT's m in Type Signature
【发布时间】:2015-09-28 00:11:36
【问题描述】:

看着MaybeT

λ: import Monad.Trans
λ: import Monad.Trans.Maybe
λ: :t MaybeT
MaybeT :: m (Maybe a) -> MaybeT m a

MaybeT的签名中,m可以是任何更高种类的类型,即* -> *吗?

我正在尝试学习 Monad Transformers,所以我很好奇为什么 m 没有 Monad 的约束。

【问题讨论】:

    标签: haskell


    【解决方案1】:

    引用Learn You A Haskell

    我们已经遇到的另一个参数化类型的例子是 Map k v 来自 Data.Mapk 是映射中键的类型,v 是值的类型。这是类型参数非常有用的一个很好的例子。只要键的类型是 Ord 类型类的一部分,将映射参数化使我们能够从任何类型映射到任何其他类型。如果我们要定义一个映射类型,我们可以在 data 声明中添加一个类型类约束:

    data (Ord k) => Map k v = ...
    

    但是,在 Haskell 中,永远不要在数据声明中添加类型类约束是一个非常严格的约定。为什么?好吧,因为我们没有得到很多好处,但是我们最终会编写更多的类约束,即使我们不需要它们。如果我们在 Map k vdata 声明中放置或不放置 Ord k 约束,我们将不得不将约束放入假设地图中的键可以排序的函数中。但是如果我们不将约束放在数据声明中,我们就不必将 (Ord k) => 放在不关心键是否可以排序的函数的类型声明中. toList 就是这样一个函数的一个例子,它只需要一个映射并将其转换为一个关联列表。它的类型签名是 toList :: Map k a -> [(k, a)]。如果 Map k v 在其 data 声明中有类型约束,则 toList 的类型必须是 toList :: Ord k => Map k a -> [(k, a)] ,即使该函数不按顺序对键进行任何比较。

    因此,即使看起来有意义,也不要将类型约束放入 data 声明中,因为无论哪种方式,您都必须将它们放入函数类型声明中。

    我希望这能回答你的问题。尽管MaybeT m a 中的m 不受约束,但隐含的假设是mMonad 的一个实例。事实上,如果m 不是Monad 的实例,那么您将无法使用MaybeT m a 值做很多事情,因为大多数函数都要求mMonad 的实例。

    【讨论】:

      【解决方案2】:

      MaybeT的签名中,m可以是任何更高种类的类型,即* -> *吗?

      没有:

      > :k MaybeT
      MaybeT :: (* -> *) -> * -> *
      

      因此,MaybeT m a 类型中的m 必须完全属于* -> *,而不是任何其他类型。

      例如,注意下面的错误:

      > :k MaybeT (State Int)
      MaybeT (State Int) :: * -> *
      
      > :k MaybeT State
          Expecting one more argument to ‘State’
          The first argument of ‘MaybeT’ should have kind ‘* -> *’,
            but ‘State’ has kind ‘* -> * -> *’
          In a type in a GHCi command: MaybeT (State)
      

      【讨论】:

        【解决方案3】:

        m 可以是任何更高种类的类型,即* -> *

        它可以是任何带有* -> * 的东西。除此之外,原则上没有限制。

        为什么m 没有Monad 的约束。

        约束是通过使用MaybeT 的函数类型提供的,而不是通过MaybeT 构造函数。除非涉及 GADT,否则向构造函数添加约束是没有用的(我相信 transformers 不使用 GADT 是为了简单和符合标准)。有关约束和数据类型声明的额外评论,请参阅 this question and its answers

        【讨论】:

          猜你喜欢
          • 2021-01-11
          • 2021-09-23
          • 2021-10-09
          • 1970-01-01
          • 2022-11-10
          • 2020-08-06
          • 1970-01-01
          • 2022-12-26
          • 2016-01-12
          相关资源
          最近更新 更多