【问题标题】:Enum type using sealed case objects (from haskell to scala)使用密封案例对象的枚举类型(从 haskell 到 scala)
【发布时间】:2016-02-01 16:47:33
【问题描述】:

我正在尝试将一些代码从 haskell 翻译成 scala 语言。 在 haskell 中,我实现了一个这样的枚举类型:

data Rank = Jack | Queen | King | Ace | Num Int deriving (Show, Eq) 

我想在scala中使用selaled case Objects实现它

sealed trait Rank
case object Jack extends Rank
case object Queen extends Rank
case object King extends Rank
case object Ace extends Rank
case object Num Int extends Rank

对于 Num Int 类型我得到一个错误的问题。我觉得应该写成一个字!任何帮助!

【问题讨论】:

  • @Shoe:当 OP 的问题与类型类无关时,我认为它不能算作 stackoverflow.com/questions/19081904/… 的重复。
  • @RégisJean-Gilles 在该问题中找到的答案代表了 ADT 和 Haskell 和 Scala 形式的类型类,这就是这个问题的全部内容。
  • 我想这值得商榷,但考虑到另一个问题的广泛性,以及这个问题的具体程度,我认为这并不适合作为重复的候选者。毫无疑问,另一个问题是相关的,无论如何值得 SaKou 阅读。

标签: scala haskell enums


【解决方案1】:

在 Haskell 中,Num 是一个需要单个类型参数(例如 Int)的类,以产生诸如 Num Int 之类的约束。所以在 scala 中你应该期待这样的事情:

case class Num(value: Int) extends Rank

请注意,scala 要求您为参数命名,这与 haskell 不同

您还缺少在scala代码中为Rank定义的ShowEq的实例,但这似乎不是问题的一部分

【讨论】:

  • 请注意,在这种情况下它应该是sealed case class,否则这将打破Rank trait 的封印。 (相比之下,objects 是天然密封的。)
  • @Madoc 谢谢,这是一个很好的说明,但并不总是需要 - 所以我不会修复我的答案。通常使用枚举的sealed,因此编译器可以生成match may not be exhaustive检查,即使不是sealed,它仍然可以继续为case class工作,因为在scala中禁止逐个继承,并且编译器不担心类到案例的继承(它不影响检查)。但是,如果您有其他理由来密封您的类型系统,此说明仍然有效
  • 仅供参考,在 Haskell 中,Num Int 不会被视为“数据类型”,而是“约束”。一旦类型检查和“去糖”将 Haskell 转换为 GHC Core(a.k.a. System FC),结果大致相同,但在 Haskell 中它们完全不同。 constraintsreflection 包有助于处理它们之间的关系。
  • 我想指出的是,包含的Haskell代码,即data Rank = ... | Num Int定义了一个new名称Num,与标准Prelude.Num无关,即一个数据构造函数并且不是一个类型类。所以,虽然我对 Scala 了解的不够多,无法确定,但我怀疑这个答案可能是基于对 Haskell 代码的误解,而不是完全符合目标。
  • @DanielWagner 我知道,我还在 scala 中定义了 Num 与 Haskell 的 Prelude.Num 无关但是我的措辞或 Haskell 术语可能是错误的,因为我主要是 scala 开发人员并且知道只有一点点haskell(而且主要是实用的一面),所以如果我说错了,请纠正我。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-08-18
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-09-17
  • 1970-01-01
相关资源
最近更新 更多