Reputation: 33
I'm trying to model the following simple Scala ADT in Haskell:
sealed trait Value
sealed trait Literal < Value
case object Null extends Literal
case class IntLiteral(value: Int) extends Literal
case class Variable(name: String) < Value
I model the Literal
trait:
Prelude> data Literal = Null | IntLiteral Int deriving (Show, Eq)
So far so good:
Prelude> Null
Null
Prelude> Null == IntLiteral 3
False
Prelude> IntLiteral 3 == IntLiteral 3
True
Now I try to introduce Variable
:
data Value = Literal | Variable String deriving (Show, Eq)
Why doesn't this work?
Prelude> Null == Variable "foo"
<interactive>:3:9: error:
• Couldn't match expected type ‘Literal’ with actual type ‘Value’
• In the second argument of ‘(==)’, namely ‘Variable "foo"’
In the expression: Null == Variable "foo"
In an equation for ‘it’: it = Null == Variable "foo"
Upvotes: 2
Views: 869
Reputation: 71119
Null
is of type Literal
, Variable "foo"
is of type Value
. There can also be a data constructor Literal
, unrelated to the type with the same name. These are just different things, living in separate namespaces, in Haskell. If you write
data Value = Literal Literal | ...
then, the first Literal
is a name of a data constructor (creates values of type Value
, in that case), the second is a name of a type.
Upvotes: 1