Make `wrapBox` work for AddrRep, TupleRep, SumRep, VecRep
!8750 (merged) beefed up our ability to allocate a box for many different representations.
Notable exceptions are AddrRep, TupleRep, SumRep and VecRep.
#22336 suggests to give up with a good error message when encountering these representations. This ticket is more ambitious: It asks for boxes for all these representations. This would be tremendously helpful for #17521 and #20269.
But since TupleRep and SumRep are recursive, there are an inifinite number of different representations to cover. Hence we can never catch all of them with a finite number of *Box data types as has been begun in ghc-prim:GHC.Types.
Proposal
-
Define a wired-in type or data family
type Box :: forall {r :: RuntimeRep}. TYPE r -> Type data family Box @r aSome instances of this family could be defined to delegate to the existing
*Boxdata types inghc-prim:GHC.Types, but the hard problem remains with unboxed tuples. This is the tricky part! We'll discuss the design below.!9353 proposes to create a data family instance on the fly, at representation
Rep. The representationTyConisR:Box[Rep], with a single data constructorMkBox[Rep] :: forall (a :: TYPE Rep). a -> R:Box[Rep]and coercionco = D:R:Box[Rep] <ty>_N :: Box @Rep ty ~R# R:Box[Rep] ty. (Side note: this data family has roles[Nominal, Representational], whereas usually onlyNominalroles are allowed in data families. This allows coercing betweenBox aandBox bwhenaandbare representationally equal.) (Kindly stole this explanation from @sheaf.)I want to add that we already have matching heap objects, if I understand
CONSTRcorrectly. Maybe we could also pickCONSTR_STATICwhen applicable. And of course we can optimise toCONSTR_p_nif we have a fitting combination for the givenr(which will be 99% of cases). So I think we might not even need to generate an excessive amount of info tables for the specialMkBoxDataCons.Having
Boxwould resolve #20269. -
#17521 also wants to offer an API to the user so that unlifted bindings at the top-level are possible (and memoised). One could imagine special, wired-in functions
box :: forall {r :: RuntimeRep} (a :: TYPE r). a -> Box a unbox :: forall {r :: RuntimeRep} (a :: TYPE r). Box a -> awhich basically desugar to something that GHC could resolve with
GHC.Core.wrapBox. It might be possible to put them in a type classBoxing, but I don't yet see the added value of doing so.
Note that (1) can be done independently of (2), but I think it makes sense to do them together.
The instances for Box might re-use many of the existing *Box types in ghc-prim:GHC.Types or might not. Not sure. But upon further reflection, I don't think !8750 (merged) brought us any closer to a satisfying resolution of either #20269 or #17521.