如何使用存在类型的异质列表获得表达问题的可扩展性

发布于 2025-02-08 18:04:30 字数 1825 浏览 1 评论 0原文

我正在尝试做的事情,

我正在尝试解决与Haskell中表达问题相似的问题。

它们有不同的表达方式和不同的操作。表达式和操作都应可扩展。

我的尝试:

为表达式创建一个类型类,并为每个操作创建类型类。

可以通过声明表达式类型类的实例以及所有受支持的操作类型类的实例来完成添加新类型的表达式。
可以通过创建新类型类并为所有应支持该操作的表达式类型声明一个实例来完成添加新操作。

class Expr a

class (Expr a) => PrettyPrint a where
    prettyPrint :: a -> String

class (Expr a) => Evaluate a where
    evaluate :: a -> Int

一些示例(并不重要):

newtype Literal = Literal Int
instance Expr Literal

data Add l r = Add l r
instance (Expr l, Expr r) => Expr (Add l r)

instance PrettyPrint Literal where
    prettyPrint (Literal x) = show x

instance Evaluate Literal where
    evaluate (Literal x) = x

instance (PrettyPrint l, PrettyPrint r) => PrettyPrint (Add l r) where
    prettyPrint (Add left right) = "(" ++ prettyPrint left ++ " + " ++ prettyPrint right ++ ")"

instance (Evaluate l, Evaluate r) => Evaluate (Add l r) where
    evaluate (Add left right) = evaluate left + evaluate right

现在我需要一个支持所有操作的表达式的异质列表。这可以在所有这些表达式类型上使用存在类型作为包装器来完成。

data SomeExpr = forall a. (Expr a, PrettyPrint a, Evaluate a) => SomeExpr a

instance Expr SomeExpr

instance PrettyPrint SomeExpr where
    prettyPrint (SomeExpr x) = prettyPrint x
    
instance Evaluate SomeExpr where
    evaluate (SomeExpr x) = evaluate x

但是现在我失去了操作的可扩展性,因为需要添加新操作作为某种定义的构造。为了使SomeEXPR提供所有操作,所有操作都必须作为约束。

是否有一种方法可以具有表达式和操作的可扩展性的表达式列表?
也应该有可能在不知道编译时表达式的确切类型的情况下创建异类列表。

edit :具有可扩展性,是指定义新型表达式(例如字面添加l r),以及对表达式的新操作(例如<<<<<代码> PrettyPrint 和在其他模块中评估)。

What I'm trying to do

I'm trying to solve a problem similar to the Expression Problem in haskell.

There are different expressions and different operations for them. Both expressions and operations should be extensible.

My attempt:

Create a type class for expressions and a type class for each operation.

Adding new types of expressions can be done by declaring an instance of the expression type class and also an instance for all supported operation type classes.
Adding a new operation can be done by creating a new type class and declare an instance of it for all expression types that should support that operation.

class Expr a

class (Expr a) => PrettyPrint a where
    prettyPrint :: a -> String

class (Expr a) => Evaluate a where
    evaluate :: a -> Int

Some examples (not that important):

newtype Literal = Literal Int
instance Expr Literal

data Add l r = Add l r
instance (Expr l, Expr r) => Expr (Add l r)

instance PrettyPrint Literal where
    prettyPrint (Literal x) = show x

instance Evaluate Literal where
    evaluate (Literal x) = x

instance (PrettyPrint l, PrettyPrint r) => PrettyPrint (Add l r) where
    prettyPrint (Add left right) = "(" ++ prettyPrint left ++ " + " ++ prettyPrint right ++ ")"

instance (Evaluate l, Evaluate r) => Evaluate (Add l r) where
    evaluate (Add left right) = evaluate left + evaluate right

Now I need a heterogeneous list of expressions that support all operations. This can be done with an existential type as a wrapper over all these expression types.

data SomeExpr = forall a. (Expr a, PrettyPrint a, Evaluate a) => SomeExpr a

instance Expr SomeExpr

instance PrettyPrint SomeExpr where
    prettyPrint (SomeExpr x) = prettyPrint x
    
instance Evaluate SomeExpr where
    evaluate (SomeExpr x) = evaluate x

But now I've lost the extensibility of operations because a new operation would need to be added as a constaint to definition of SomeExpr. In order for SomeExpr to provide all operations, all operations must be given as constraints.

Is there a way to have a heterogeneous list of expressions while still having extensibility of both expression types and operations?
It should also be possible to create the heterogeneous list without knowing the exact types of the expressions at compile time.

Edit: With extensibility I mean defining new types of expressions (like Literal and Add l r), as well as new operations on expressions (like prettyPrint and evaluate) in other modules.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文