【问题标题】:Discriminated type unions有区别的类型联合
【发布时间】:2025-12-30 15:10:12
【问题描述】:

有没有办法在 Haskell 中模仿 TypeScript 的可区分类型联合?我想做以下事情:

data A = B | C | D
data W = X | Y | Z

data FinalType = A | W

我知道最后一个定义将为FinalType 创建两个值构造函数AW。我现在可以通过以下方式正确地制作FinalType

data FinalType = B | C | D | X | Y | Z

但这不是很整洁,并且在添加了很多值构造函数之后会变得很烦人。有没有办法在 Haskell 中缓解这种情况?

【问题讨论】:

  • data FinalType = A A | W W?或者您可以使用现有的 Either 类型构造函数和类型同义词:type FinalType = Either A W
  • 可以提供TS sn-p吗?你也可以解释为什么你用这种方式使用联合。也许有惯用的 Haskell 替代方案。

标签: haskell algebraic-data-types discriminated-union


【解决方案1】:

正如罗宾·齐格蒙德建议的那样,

data FinalType = A A | W W

会起作用。这采用 A BA CW Z 等值。除非您在这里需要懒惰(相对不太可能),否则您可能应该使构造函数严格:

data FinalType = A !A | W !W

这样,计算FinalType 类型的值就可以保证计算出它的实际内容。

请注意,与 Typescript 的 union 类型不同,Haskell 的 sum 类型始终是可区分的。这就是 AW 构造函数在这里所扮演的角色,而不是有一个公共字段来指示正在使用的类型。初学者可能会对AW 名称的重载感到困惑;你可以通过定义来更明确

data FinalType = FinalA A | FinalW W

【讨论】:

  • 谢谢,我猜这对我有用。虽然有没有办法在haskell中进行正常类型的联合?就像我可以在FinalType 中直接访问AW 的值构造函数?
  • @HariomNarang,不,这在 Haskell 中并不是真正的东西。