【问题标题】:Why is there a type class Measured for Data.FingerTree instead of just a function?为什么有一个类型类 Measured for Data.FingerTree 而不仅仅是一个函数?
【发布时间】:2013-08-11 01:05:12
【问题描述】:

我不明白为什么FingerTree 是用类型类Measured 实现的。

我正在尝试实现一系列具有与 monoid 相同的默认度量的 monoid,因此我编写了以下内容。

instance Monoid a => Measured (Sum Int, a) a where
  measure x = (Sum 1, x)

当然,由于FingerTree 本身就是Measured,这是不可能的,因为我们会得到类型类重叠。

什么时候把这个单一的函数抽象成一个类型类才有意义?为什么我们不能只定义FingerTree 以便我们可以将度量函数提供给构造函数?

如果有办法解决这个问题也很高兴。我每次都可以为我的特定用例定义一个新实例,但也许有更好的方法。

【问题讨论】:

    标签: haskell


    【解决方案1】:

    这是类型类函数解析和“直接”函数解析之间普遍摩擦的一个实例。正如您在此处所指出的那样,有很多时候支持直接,但通常可以说明类型类实例必须支持的特定法律,人们发现使用类型类解析是有意义的。

    我认为不可能有一个更好的“正确”答案,但更频繁地使用直接方法确实有很好的论据。

    在这种情况下,需要更多的特异性来帮助编译器理解应该解析哪个实例。虽然任何Monoid 都可以有一个“计数并组合”Measured 实例,但尚不清楚这是规范实例。由于Measured 的类要求Measured v a | a -> v 我们必须规范地选择v

    最可能的方法是创建一个newtype 包装器

    newtype Counted a = Counted a
    instance Monoid a => Measured (Sum Int, a) (Counted a) where
      measure (Counted x) = (Sum 1, x)
    

    这为我们提供了所需的规范性。这可能在某些情况下比直接传递Monoid 函数字典更方便。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2010-09-12
      • 2023-03-18
      • 1970-01-01
      • 2017-04-05
      • 1970-01-01
      • 1970-01-01
      • 2019-12-02
      • 1970-01-01
      相关资源
      最近更新 更多