首页 > 解决方案 > 创建相同类型但不同类型的值列表

问题描述

我是 Haskell 的新手,正在尝试做一些我确信很容易的事情,但我没有看到正确的方法。

我想要的是一个特定类型类的值列表,但该类型类的不同类型。例如:

class Shape a where
  area :: a -> Double
  numVertices :: a -> Integer

data Triangle = Triangle {...}
data Square = Square {...}

instance Shape Triangle where ...  
instance Shape Square where ...

x = [Triangle (...), Square (...)]

我收到编译器错误,因为列表具有不同的类型。做我在这里想做的事情的正确方法是什么?我唯一能想到的就是做这样的事情:

data WrappedShape = WrappedShape {
    getArea :: () -> Double
  , getNumVertices :: () -> Integer
}

wrap s = WrappedShape {
    getArea = \ () -> area s
  , getNumVertices = \ () -> vertices s
}

x = [wrap (Triangle (...)), wrap (Square (...))]

这可行,但它在样板中很重,因为我必须有效地定义 Shape 两次并且使用不同命名的成员。做这种事情的标准方法是什么?

标签: haskell

解决方案


如果你只需要几个不同的形状,你可以枚举每个形状作为构造函数,这里是一个例子:

data SomeShapes = Triangle {...}
                  | Square {...}

instance Shape SomeShapes where 
    area (Triangle x) = ...
    area (Square x) = ....

现在你可以把它们放在一个列表中,因为它们是相同类型的 SomeShapes

[Triangle {...}, Square {...}]

推荐阅读