I'm learning Haskell along with Scala. I tried to do define the following Scala type in Haskell, but failed:
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
Could someone give me an example?
In scala, union types are emulated with a sealed class/trait with a number of subclasses containing the individual cases. These can be defined in Haskell directly:
data Expr = Value Int | Add Expr Expr | Subtract Expr Expr
this differs from scala in that Value
, Add
and Subtract
are constructors for the Expr
type, whereas in Scala
the individual case classes also have their own type which can be referenced directly e.g.
def printValue(v: Value): Unit = { println(v.n) }
As an alternative to what others posted, here's a solution which uses a syntax closer to scala, relying on the small extension 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
https://wiki.haskell.org/Algebraic_data_type
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With