Reputation: 297
I want to have the following data type in Haskell :
data Exp = Add Exp Exp
| Var String
| Let (Var String) Exp Exp
| Int Int
However, using (Var String) like that is not allowed. I could use Exp instead of (Var String), but I don't want an Int to be allowed there, so how can I solve this?
Upvotes: 0
Views: 570
Reputation: 64740
You could define a newtype wrapper Var
or just use String
. First the newtype wrapper example:
newtype Var = V String
-- ^ "Var" here is a type declaration. "V" is declaring a data constructor.
data Exp = Add Exp Exp
| Var Var -- The first "Var" here is declaring a data constructor. The second is referring to the type.
| Let Var Exp Exp -- "Var" here is referring to the type
| Int Int
Or just with strings:
data Exp = Add Exp Exp
| Var String
| Let String Exp Exp
| Int Int
EDIT: The point my comments were trying to make is probably unclear. In your use of Var, such as Let (Var String) Exp Exp
, you tried to use a constructor named Var
(and it's field, String
) in a location that requires a type. Each data constructor can be used to build a value of the type (Exp in this case) and can not be further distinguished by the type system. In lieu of an additional data declaration you can't distinguish between a value of type Exp that is a Var
from one that is an Add
, Let
, or Int
.
Upvotes: 4