TEA - Erweiterung
Erweiterte Elm-Architektur
Um Zufallszahlen von der Laufzeitumgebung erzeugen lassen zu können, wechseln wir auf eine andere Version der Elm-Architektur. Die Grafik verdeutlicht den Ablauf. Wir gehen wieder davon aus, dass wir einen Datentyp bzw. ein Typ-Alias für Msg und Model definiert haben.
Es gibt im Vergleich zur bisherigen Architektur einige Änderungen:
-
init:
Zu Beginn haben wir nicht einfach nur ein initiales Datenmodell,
sondern eine Funktion, die aus einem Startwert, der außerhalb unseres
Programms liegt, ein initiales Datenmodell erzeugt.
Der Startwert könnte z.B. die aktuelle Uhrzeit, die im Browser
über JavaScript ermittelt wird, oder ein im Browser gespeicherter Wert sein.
In diesem und den meisten folgenden Abschnitten wird dieser Startwert
leer sein. Für einen leeren Wert gibt es in Elm den speziellen Typ
(), der nur einen einzigen Wert hat, nämlich(). Man bezeichnet diesen leeren Datentyp auch als Unit. Zusätzlich wird einCmd Msgzurückgegeben. Dabei handelt es sich um ein Kommando, das von der Laufzeitumgebung ausgeführt werden soll. Das Kommando kann z.B. lauten: "Erzeuge eine Zufallszahl und sende sie als Nachricht an die update-Funktion zurück." -
view:
Die view-Funktion bleibt unverändert. Sie erzeugt weiterhin eine abstrakte Darstellung
der Webseite vom Typ
Html Msg, die von der Laufzeitumgebung in eine konkrete Webseite umgewandelt wird und potentiell Nachrichten vom TypMsgerzeugt. -
subscriptions:
Die subscriptions-Funktion ermöglicht es, externe Ereignisse zu abonnieren,
z.B. könnte man alle zehn Sekunden eine Nachricht mit dem Wert
Tickempfangen. In diesem Abschnitt werden wir diese Funktion nicht nutzen, müssen aber dennoch eine Implementierung dafür bereitstellen, die in diesem Fall einfach immerSub.nonezurückgibt, also keine Ereignisse abonniert. - update: Die update-Funktion erhält wie bisher auch eine Nachricht und das aktuelle Datenmodell. Neu ist, dass sie - genau wie die init-Funktion - zusätzlich ein Kommando zurückgibt, das von der Laufzeitumgebung ausgeführt werden soll.
Um das alles umsetzen zu können, müssen wir die Funktion
Browser.sandbox durch Browser.element ersetzen.
Das folgende Programm demonstriert die neue Architektur.
Es fehlen die Imports und die Definition von wuerfelKommando,
das Programm ist also so noch nicht lauffähig.
type alias Model =
{ zahl : Int }
type Msg
= NeueZahl Int
| ButtonKlick
init : () -> ( Model, Cmd Msg )
init _ =
( { zahl = 0 }, wuerfelKommando )
update : Msg -> Model -> ( Model, Cmd Msg )
update msg model =
case msg of
NeueZahl z ->
( { zahl = z }, Cmd.none )
ButtonKlick ->
( model, wuerfelKommando )
view : Model -> Html Msg
view model =
div []
[ text (String.fromInt model.zahl)
, button [ onClick ButtonKlick ] [ text "Neu würfeln" ]
]
subscriptions : model -> Sub Msg
subscriptions _ =
Sub.none
main =
Browser.element
{ init = init
, view = view
, update = update
, subscriptions = subscriptions
}
Aufgabe
(a) Analysiere das Programm und beschreibe die einzelnen Abschnitte.
Gehe dabei insbesondere auf die verschiedenen Funktionen ein.
Interpretiere den Ausdruck wuerfelKommando als
"Erzeuge eine Zufallszahl zwischen 1 und 6 und sende sie z.B. als Nachricht
NeueZahl 3 an die update-Funktion."
(b) Stelle den Prozess in einem Rollenspiel dar.
Eine Person spielt die Rolle der Laufzeit-Umgebung,
je eine Person stellt die init-, view- und update-Funktion dar.
Da wir uns momentan nicht mit Subscriptions beschäftigen,
kann diese Rolle weggelassen werden.
Nutze Papierzettel, um Daten wie z.B. Nachrichten, Kommando,
abstrakte Html-Darstellung und die Webseite zu visualisieren.