<div dir="ltr">Making best use of Trex needs a different mindset vs H98 datatypes with named fields. (Or indeed vs named-fields data structures in many languages) There's some examples around in the Trex/Hugs material, but I've seen nothing showing this:<div><br></div><div>>    type WPoint r  = (x :: Float, y :: Float | r)            -- r extended "with Point"<br>>    type WRadius r = (radius :: Float | r)<br>>    type WColour r = (colour :: String | r)<br>>    type ColouredCircle = Rec( WColour (WRadius (WPoint EmptyRow)))<br></div><div><br></div><div>The idea is rather than nest 'Point' as a datatype inside 'Circle' 'plug and play' components (such as Point, Radius) to give a structural type. It's interesting and impressive that the Wxxx synonyms take an argument of kind row, return a result of kind row. `EmptyRow` in the last line is a Hugs-defined Row constant that 'plugs' the end of the composed components, just as `emptyRec` does for Trex Records.</div><div><br></div><div>I'd love to write that last type as</div><div><br></div><div>>    type MkRec r = Rec( r EmptyRow)</div><div>>    type ColouredCircle = MkRec (WColour . WRadius . WPoint)</div><div><br></div><div>But of course type synonyms -- even with parameters -- are not functions; can't be composed; can't be passed to higher-order type synonyms.</div><div><br></div><div>Components like WPoint can be arguments to type-parametric functions for record subtyping: such as a generic routine to 'move' any shape by modifying its x, y coordinates. 'Move' in scare quotes because that's returning a copy of the shape's data structure with modified coordinates, not poking values into an object/reference.</div></div>