Record types can contain a type variable to say “I don’t care what else is in this record as long as these fields are”. It’s really useful for passing your model to your view function, but using the type system to show that the view doesn’t rely on most of the fields, and it lets you fuzz smaller inputs.
Example:
distance : { a | x : Float, y : Float } -> { b | x : Float, y : Float } -> Float
distance p1 p2 = ...
dist = distance {x=2, y=3} {x=4, y=5, z=6}
By using different type variables, we say that the other fields in the two records don’t need to be the same. That allows us to pass two different types and get a sensible answer out.
(Unfortunately, there’s not a way to take either 2D or 3D coordinates and default aTwoDimensionalPoint.z to zero. Define your 3D type and then have a function that takes two arguments and fill in the zero.)