Lucas Buhl-Nielsen
Lucas Buhl-Nielsen

Reputation: 119

Adding additional parameters to data constructors using infix operators

I have written a data constructor like

data Expr = IntL Integer | Expr :*: Expr

and would like to annotate it with extra constructor parameters (such as positional information) like this:

data Expr = IntL Integer Pos | Expr :*: Expr Pos

However GHC does not like this:

Expected kind '* -> *' but 'Expr' has kind '*' 
In the type 'Expr Position'
In the definition of data constructor ':*:'
In the data declaration for 'Expr'

I know I could use something like Mul Expr Expr Pos as a work around or even wrap Expr in another data constructor, but I'd really like to use the infix operator and cannot figure a way to do so! Is this possible?

I've tried wrapping the constructor in brackets:

data Expr = IntL Integer Pos | (Expr :*: Expr) Pos

And also making :*: a prefix:

data Expr = IntL Integer Pos | (:*:) Expr Expr Pos

but this does not allow me to pattern match in the same way. I'm not sure this even makes sense as a type constructor but thought I'd ask just in case.

Upvotes: 0

Views: 84

Answers (1)

willeM_ Van Onsem
willeM_ Van Onsem

Reputation: 477749

It might be better to do this with an extra constructor, so:

infixl 6 :*:
infixl 7 :@
data Expr = IntL Integer | PosExpr :*: PosExpr
data PosExpr = Expr :@ Pos

Then you can construct items with:

(IntL 5 :@ foo :*: IntL 6 :@ bar) :@ qux

Upvotes: 3

Related Questions