替代代数数据类型,在记录语法中有许多构造函数

问题描述 投票:2回答:2

我有一个自定义数据类型,包含景观元素(云,太阳,山等)。我需要有一个列表,所以我不能使用不同的类型和一个常见的类型类。

它们共享构造函数中的大多数字段,但有些字段具有其他不具有的属性(例如,云是否正在下雨)。

截至目前,我有一种具有不同构造函数的数据类型:

data Element = Sun {
  elemColorStart :: Color,
  elemColorEnd :: Color,
  elemCoords :: Coords,
  elemPeriod :: Float,
  elemSize :: Float,
  elemSteps :: Step,
  elemTime :: Float
}
| Cloud {
  elemKind :: CloudKind,
  elemColorMain :: Color,
  elemCoords :: Coords,
  elemRans :: [Float],
  elemSize' :: Size',
  elemSteps :: Step,
  elemTime :: Float
}
... etc

或者,我可以拥有一个具有所有可能属性的通用构造函数,如果不需要它们就不会初始化它们,尽管这看起来更糟糕。

这看起来不是很“Haskelly”,实际上这种方法通常是面向对象的。我究竟做错了什么?任何其他可能的方法都是受欢迎的;它不是一个任务,所以我没有任何限制。

haskell record algebraic-data-types
2个回答
9
投票

将事物隔离到他们自己的数据类型中并将qazxsw poi作为它们的总和:

Element

现在,您可以为孤立的事物提供专用的API,就像分离关注点所带来的所有好事一样。

哦,顺便说一句,我已经删除了字段名称的前缀,因为现在我们有data Sun = Sun { colorStart :: Color, colorEnd :: Color, coords :: Coords, period :: Float, size :: Float, steps :: Step, time :: Float } data Cloud = Cloud { kind :: CloudKind, colorMain :: Color, coords :: Coords, rans :: [Float], size :: Size', steps :: Step, time :: Float } data Element = SunElement Sun | CloudElement Cloud 扩展名。

顺便说一下,你会发现DuplicateRecordFields很有用。


0
投票

尼基塔答案的一个转折是使用一个名为this question的ADT控制在SharedSun中找到的区域。如果您愿意,可以将其与OO的继承进行比较。

Cloud
© www.soinside.com 2019 - 2024. All rights reserved.