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
.