2015-11-21 15 views
5

Ich versuche, eine Bibliothek von Elm 0.15 zu 0.16 zu migrieren. Der Datensatzerweiterungsmechanismus wurde entfernt.Alternative zu Elm Datensatzerweiterung

My library bietet Physikberechnungen für Körper (als Datensatz dargestellt) und verwendet Datensatzerweiterung, damit Benutzer Beschriftungen und andere Metadaten zu den Körpern hinzufügen können.

Meine example code zeigt diese Anwendung durch ein Etikett an alle Stellen nach ihrer Erstellung Zugabe:

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

Diese Liste der markierten Stellen auch in die Bibliothek übergeben wird:

main = Signal.map scene (run labeledBodies tick) 

Welche Art von arbeitet: ein meta Parameter in die Body wie diese hartzucodieren:

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 
} 

Das macht die API jedoch etwas ungeschickter, weil sie die Hilfsfunktionen zwingt, einen zusätzlichen Parameter zu übernehmen. Gibt es eine elegantere Art, mit dieser Veränderung umzugehen?

+0

Ist "Label" wirklich notwendig auf der Platte zu beginnen? Könnten Sie stattdessen 'bodyLabel' aus der' run' Funktion aufrufen? –

+0

In diesem Fall ja (aber es würde jedes Mal zusätzliche Arbeit machen), aber im allgemeinen Fall nein: Ich möchte auch andere Metadaten verfolgen können, die nicht vom Körper abhängig sind (zB Hitpoints, unique id, was auch immer) –

Antwort

1

Was ist, wenn das Feld meta den Typ Dict String String hat? Dann müssten Sie keine verrückten Variablen-Ungeschicklichkeiten machen. Sie verlieren jedoch die Garantie, dass alle Datensätze, die Sie übergeben, in der Tat Etiketten haben, so dass Sie mit einem Maybe String arbeiten müssen, wenn Sie Dict.get "label" r.meta tun.

+0

Ich habe erwogen, ein Feld für eine feste ID oder Metadaten hinzuzufügen, aber das wird nicht so gut für den allgemeinen Fall funktionieren, wo ich nicht nur String-Werte verfolgen will. –

1

Wie wäre es mit einem markierten Union-Typ?

type BodyWithMeta = 
    LabeledBody Body String 

labeledBodies = map (\b -> LabeledBody b (bodyLabel b.restitution b.inverseMass)) someBodies 
+0

Dies ist möglicherweise nicht vollständig aus der Frage klar. Aber ich möchte, dass die 'run'-Funktion nicht die Verbindung zwischen Körper und angehängten Metadaten verliert. Mit Ihrem Vorschlag hätte "run" den Typ "LabeledBody" zu kennen, während ich gehofft hatte, die Metadaten generisch zu halten. –

+0

braucht 'run' das Label überhaupt? – robertjlooby

+0

'run' braucht es nicht (es weiß nichts davon), aber es muss ein Teil der Datenstruktur sein, die' run' mit –