Bare Frage:
Gibt es eine Möglichkeit, ein Paar Signale zu definieren, die in Elm voneinander abhängen?
Präambel:
Ich versuche, ein winziges Cookie-Clicker-ähnliches Browserspiel zu schreiben, in dem der Spieler Ressourcen sammelt und sie dann ausgibt, um autonome Ressourcen sammelnde Konstrukte zu kaufen, die beim Kauf teurer werden. Das beinhaltet drei relevante Signale: gathered
(wie viel Ressourcen der Spieler gesammelt hat), spent
(wie viel Ressource hat der Spieler bereits ausgegeben) und cost
(wie viel kostet ein Upgrade).
Hier ist eine Implementierung:
%Vor%Dies wird zwar gut übersetzt, aber wenn ich es in eine HTML-Datei einbetten will, in der die entsprechenden Tasten angeschlossen sind, um Nachrichten an die entsprechenden Ports oben zu senden, bekomme ich den Fehler
%Vor% Das Problem scheint darin zu bestehen, dass cost
von canAfford
abhängt, was von balance
abhängt, was von spent
abhängt, was wiederum von cost
abhängt.
Wenn ich die Kostenzeile so ändere, dass
%Vor%es funktioniert wie erwartet (außer dass der Spieler in negative Ressourcen investieren darf, was ich gerne vermeiden würde).
Irgendwelche Ideen?
Nein , in Elm gibt es keinen allgemeinen Weg, gegenseitig rekursive Signale zu definieren.
Das Problem liegt in der Einschränkung, dass ein Signal
in Elm immer einen Wert haben muss. Wenn die Definition von cost
canAfford
erfordert, aber canAfford
in cost
definiert ist, besteht das Problem darin, mit der Auflösung des Anfangswerts des Signals zu beginnen. Dies ist ein schwieriges Problem zu lösen, wenn Sie in Bezug auf gegenseitig rekursive Signale denken.
Gegenseitig rekursive Signale haben alles mit vergangenen Signalwerten zu tun. Mit dem Konstrukt foldp
können Sie das Äquivalent von gegenseitig rekursiven Signalen bis zu einem bestimmten Punkt angeben. Die Lösung des Anfangswertproblems wird durch ein explizites Argument für foldp
, das der Anfangswert ist, gelöst. Die Einschränkung ist jedoch, dass foldp
nur reine Funktionen benötigt.
Dieses Problem lässt sich nur schwer so erklären, dass keine Vorkenntnisse erforderlich sind. Also hier ist eine andere Erklärung, basierend auf einem Diagramm, das ich von Ihrem Code gemacht habe.
Nehmen Sie sich Zeit, um die Verbindungen zwischen dem Code und dem Diagramm zu finden (beachten Sie, dass ich main
weggelassen habe, um das Diagramm zu vereinfachen). A foldp
ist ein Knoten mit einer Schleife zurück, sampleOn
hat einen Blitz usw. (Ich habe sampleOn
bei einem konstanten Signal in always
umgeschrieben). Der problematische Teil ist die steigende rote Linie mit canAfford
in der Definition von cost
.
Wie Sie sehen können, hat eine grundlegende foldp
eine einfache Schleife mit einem Basiswert. Dies zu implementieren ist einfacher als ein beliebiges Rückschleifen wie das Ihre.
Ich hoffe, Sie verstehen das Problem jetzt. Die Einschränkung ist in Elm, es ist nicht deine Schuld Ich löse diese Einschränkung in Elm auf, obwohl es einige Zeit dauern wird.
Obwohl es schön sein kann, Signale zu benennen und mit diesen zu arbeiten, hilft es bei der Implementierung von Spielen in Elm normalerweise, ein anderes zu verwenden Programmierstil . Die Idee im verlinkten Artikel besteht darin, Ihren Code in folgende Teile aufzuteilen:
Mouse
, Time
und Ports in Ihrem Fall. cost
, balance
, canAfford
, spent
, gathered
usw. Verknüpfen Sie alles mit etwas wie main = view <~ foldp update modelStartValues inputs
.
Insbesondere würde ich es so schreiben:
%Vor%Tags und Links elm