【问题标题】:Type classes, associated families -> containers, keys, and elements: Who is who?类型类、关联族 -> 容器、​​键和元素:谁是谁?
【发布时间】:2013-05-06 04:16:41
【问题描述】:

阅读type families on haskellwiki,我看到了例子

class Collects ce where
  type Elem ce
  empty  :: ce
  insert :: Elem ce -> ce -> ce

这对我来说很有意义,因为我使用了我的(可能适得其反的)OOP 隐喻——Collects 的一个实例具有关联类型(同义词)Elem ce。集合在某种程度上比元素“更大”。

我对关联数据系列的示例感到困惑,因为它不适合该模型。

 class GMapKey k where
   data GMap k :: * -> *
   empty       :: Gmap k v
   insert      :: k -> v -> GMap k v -> Gmap k v

地图收集了 vs,感觉比 vs 和 ks“更大”。但似乎 GMapKey 有一个关联的 GMap,而我预计这种关系会走向另一个方向。

当我在数据系列和类型同义词系列之间进行选择时,这是要遵循的模式吗(数据系列:容器是关联类型,类型同义词系列:元素是关联类型)?或者这 IS A / HAS A 区别无关紧要,两个例子可以互换?

【问题讨论】:

    标签: haskell containers idioms type-families


    【解决方案1】:

    IS A/HAS A 关系在这里是一个不好的比喻。更好的直觉是“关联”或“专门化(某种类型)到”。在实践中,这意味着当你解析一个类型时

    f :: GMapKey k => k -> GMap k v -> v
    

    第一个和第二个参数都是多态的,但必须统一。没有必要将一个包含在另一个中。


    要决定使用哪个“方向”,您必须考虑事物如何概括。如果您定义一个与“键”相关联的类型的“容器”类,那么您就是说每个容器类型在单个键上“实例化此类接口”。这是一个多对一的关系,因为每个“容器”都有一个关联的“键”,但“键”可以是许多容器的关联类型。如果换一种方式,则说明每个“键”都限制为特定类型的“容器”,但容器可能有许多不同的键可以索引它们。

    【讨论】:

    • 谢谢。我会尽量记住那个助记符,直到更深层次的直觉陷入:)
    • 了解(更多)关于类型类如何工作的一种方法是研究 Prolog。类型统一、类型类统一和逻辑编程都是类似的范式。
    【解决方案2】:

    我建议这样想:GMap 系列与 k 相关联,并且您必须有一个与 k 关联的 GMap 类型系列实例,以便 k 用作GMapKey.

    这些选项之间的选择更多地取决于您的需求,而不是其他任何事情。当键类型决定映射实现时,GMap k 方法更可取:例如对Int 键使用IntMap,但对其他键使用另一种类型的Map...

    【讨论】:

    • 谢谢路易斯,这很有意义。我可能错过了这一点,因为我面前的用例不涉及不同键的不同实现。我只是使用类型族来避免具有功能依赖的多参数类型类。
    • @ImAlsoGreg 我非常同意避免多参数类型类/功能依赖是可以的。类型族要好得多。
    猜你喜欢
    • 1970-01-01
    • 2015-08-31
    • 1970-01-01
    • 2023-04-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-10-28
    • 2010-11-30
    相关资源
    最近更新 更多