我正在学习Haskell和Scala。我试图在Haskell中定义以下Scala类型,但失败了:
sealed trait Expr
case class Value(n: Int) extends Expr
case class Add(e1: Expr, e2: Expr) extends Expr
case class Subtract(e1: Expr, e2: Expr) extends Expr
有人可以给我一个例子吗?
我正在学习Haskell和Scala。我试图在Haskell中定义以下Scala类型,但失败了:
sealed trait Expr
case class Value(n: Int) extends Expr
case class Add(e1: Expr, e2: Expr) extends Expr
case class Subtract(e1: Expr, e2: Expr) extends Expr
有人可以给我一个例子吗?
在Scala中,联合类型是通过使用带有多个子类的封闭类/特质来模拟的,每个子类都包含各个情况。这些可以直接在Haskell中定义:
data Expr = Value Int | Add Expr Expr | Subtract Expr Expr
这与Scala不同,Value
、Add
和Subtract
是Expr
类型的构造函数,在Scala中,各个单独的case类也有自己的类型,可以直接引用。
def printValue(v: Value): Unit = { println(v.n) }
作为其他人发布的替代方案,这里提供了一种使用类似于scala的语法的解决方案,依赖于小型扩展GADTSyntax
。
{-# LANGUAGE GADTSyntax #-}
--- sealed trait Expr
data Expr where
-- case class Value(n: Int) extends Expr
Value :: Int -> Expr
-- case class Add(e1: Expr, e2: Expr) extends Expr
Add :: Expr -> Expr -> Expr
-- case class Subtract(e1: Expr, e2: Expr) extends Expr
Subtract :: Expr -> Expr -> Expr
data Expr = Value Int | Add Expr Expr | Subtract Expr Expr