Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Alternative to Elm record extension

Tags:

elm

records

I am trying to migrate a library from Elm 0.15 to 0.16. The record extension mechanism has been removed.

My library offers physics calculations on bodies (represented as record), and uses record extension to allow users to add labels and other metadata about the bodies.

My example code shows this use by adding a label to all the bodies after their creation:

labeledBodies = map (\b -> { b | label = bodyLabel b.restitution b.inverseMass }) someBodies

This list of labeled bodies is also passed to the library:

main = Signal.map scene (run labeledBodies tick)

What sort of works: hardcoding a meta parameter into the Body like this:

type alias Body a = {
  pos: Vec2, -- reference position (center)
  velocity: Vec2, -- direction and speed
  inverseMass: Float, -- we usually use only inverse mass for calculations
  restitution: Float, -- bounciness factor
  shape: Shape,
  meta: a
}

But this makes the API more clumsy because it forces the helper functions to take an extra parameter. Is there a more elegant way to deal with this change?

like image 817
Justin Kaeser Avatar asked Oct 31 '22 15:10

Justin Kaeser


2 Answers

What if the meta field had type Dict String String? Then you wouldn't have to do any crazy type variables clumsiness. However, you lose guarantees that all the records you pass in do indeed have labels, so you have to work with a Maybe String when you do Dict.get "label" r.meta.

like image 151
mgold Avatar answered Nov 08 '22 15:11

mgold


What about using a tagged union type?

type BodyWithMeta = 
  LabeledBody Body String

labeledBodies = map (\b -> LabeledBody b (bodyLabel b.restitution b.inverseMass)) someBodies
like image 45
robertjlooby Avatar answered Nov 08 '22 17:11

robertjlooby