I am trying to create the following datatypes:
data ExprValues = ExprNum Int |
ExprIdent String |
ExprChar Char |
ExprString String
deriving(Eq, Show, Read)
data ExprOverall = ExprFunCall ExprValues --correct this to use ExprIdent solely
deriving(Eq, Show, Read)
However, as it is indicated in the comment, I want that ExprValues next to the ExprFuncall to accept ExprIdent String only, not the other ExprValues. How am I able to do it?
First off, if you want to allow only the constructor, why not just “inline” it – store a
String
right inExprOverall
and be done?But more generally, this sort of restriction can be implemented with GADTs. Often, especially for such AST-like types, you want to express the overall type the expression stands for. There,
ExprIdent
might be polymorphic while the others are concrete:Then, for use in
ExprOverall
you select a unique tag-type that is only applicable to theExprIdent
constructor (because that allows any type variablea
, whereas the others are specific to a concrete type).