Flatten data types extending other data types in STG
This idea was triggered by https://mail.haskell.org/pipermail/haskell-cafe/2018-February/128570.html although it does not solve that particular case. Hence I don’t know if there is any practical use for it, but I wanted to jot it down.
Consider a data type
data Result = Ok !Foo | NotOK Error
Foo is a concrete algebraic data type with $n$ constructors.
Then the following transformation should be safe:
Do not generate an info table for
NotOKthe constructor number $n+1$.
Replace calls to
case r as b of Of f -> E[b,f] | NotOk e -> E[b,e]
case r as b of DEFAULT -> E[b,b] | NotOk e -> E[b,e]
This effectively makes every constructor or
Foo a constructor of
Ok, and eliminates the pointer indirection introduced by
Foo. Checking if a
Ok is now a simple check of the pointer tag (if
Result do not have too many constructors).
Result could have additional constructors, but only one can be eliminated. This one constructor needs to
- have one argument
- be strict in that argument
- that argument must be an algebraic data type (even after this flattening) does not have
NotOkas a constructor.
We currently cannot do this in
Core, but we could if our safe coercions were directed.
Do you think you have a case where this could give a performance boost? Maybe some parser library? You can try this now using pattern synonyms and
unsafeCoerce. If you think there is something to be gained here, then we can consider implementing this.