gpt4 book ai didi

haskell - 如何在保留类型类成员身份的同时将值包装在新数据类型中?

转载 作者:行者123 更新时间:2023-12-02 16:04:51 26 4
gpt4 key购买 nike

我是一个 Haskell 初学者,用 Haskell 为一些简单的语言编写了一个玩具编译器,在完成解析器之后,我开始研究第一个“阶段”(类型检查、一些简化、代码生成等)。我的 AST 数据类型如下所示:

data Ast a = ConstInt Int a | Variable String a | SomeComplexThing .... a

重点是,我希望在每次传递后使用该a槽来存储信息:比如说,在解析之后我们有一个Ast Position,然后在类型检查之后我们有一个 Ast (Position,TypeInfo) 等等。

但是,我希望在舞台上独立访问此有效负载中的值。截至目前,在不同的阶段,元组具有不同的类型,因此没有同质的自动化方法来执行此操作。如果我要移除一个舞台,那么一切都将改变。

所以,作为 haskell 菜鸟的我想:类型类!

现在,我可以轻松创建 TypeInfoHolder 类型类和 PositionHolder 类型类,等等

class TypeInfoHolder a where
getTypeInfo::a->TypeInfo

还有一个

  data TypeInfoHolderObj a = TypeInfoHolderObj a TypeInfo

并将其设为 TypeInfoHolder 的实例。

现在我想以某种方式自动确保每个 TypeInfoHolderObj a 也是 a 所属的所有类的实例,即对于每个类型类 a 实现的 A,然后 TypeInfoHolderObj a 也通过将类的函数应用于 TypeInfoHolderObj 的 a 成员来实现

出于好奇,我只是想知道这一点:这似乎是经常出现的事情。

最佳答案

您似乎有大约两个问题。

  1. 使用类型类提供从许多其他类型中转换某种类型的能力是一个好主意吗?而且,

  2. 有没有办法让 TypeInfoHolderObj a 等类型继承 a 的所有实例

(1) 的答案存在一些争议,因为类型类的“正确”使用存在一些争议。就我个人而言,我认为答案是"is",并且它在 Lenses 文献中得到了一些支持,其中像 HasX 这样的类型类很常见。不过,这绝对是一个风格问题,因此很难得到有意义的答案,尤其是从 Stack Overflow 中。

(2) 的答案是“否”,并且很容易说明原因。仅考虑需要自动派生的众多示例实例之一

instance Monoid a => Monoid (TypeInfoHolderObj a) where ...

对于某些类型(可能是 newtypes 的类型),此实例派生可以自动完成(请参阅 GeneralizedNewtypeDeriving),但对于 TypeInfoHolderObj 来说,它是除非 TypeInfo 共享 Monoid 实例,否则不可能。如果是这样,我们就可以做到

  mempty = TypeInfoHolderObj mempty mempty
mappend (TypeInfoHolderObj a b) (TypeInfoHolderObj c d) =
TypeInfoHolderObj (mappend a c) (mappend b d)

一般来说,我们不知道自动派生此类实例所需的所有假设。不过,可以猜测它们何时会发生,因为只要您的实例看起来有点像,它们就会起作用

class Foo a where ...
instance (Foo a, Foo b) => Foo (a, b) where ...

因为,实际上,TypeInfoHolderObj a只不过是(a, TypeInfo)

关于haskell - 如何在保留类型类成员身份的同时将值包装在新数据类型中?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25083677/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com