0

Ich beginne gerade meine FP-Reise beim Lernen von Scala.Unveränderliche Art, den Zustand in scala zu behandeln

Jetzt muss eine List[String] in einer ungefilterten Webanwendung gepflegt werden. Wenn eine POST Anfrage an einen Endpunkt gesendet wird, sollte die Liste aus einer Datei aktualisiert werden. Und die Liste wird verwendet, wenn eine GET-Anfrage an denselben Endpunkt gesendet wird.

Jetzt versuche ich zu vermeiden, var zum Speichern der Liste zu verwenden. Ich weiß manchmal, dass wir var verwenden müssen, aber nur neugierig, dass es eine elegante Möglichkeit gibt, mit dem Fall umzugehen. Ich habe versucht mit scalaz.State Iterator und Steam. Aber stecken geblieben, da ich keine Ahnung habe, wie man den aktuellen unveränderlichen Zustand an die nächste Anfrage weitergibt. Irgendein Vorschlag, bitte?

def update = State(l => { 
    retrieve(filepath) match { 
    case Success(lines) => (lines.split("[,\n\r]").toVector.map (_.trim), true) 
    case Failure(_) => { 
     log.error(s"Cannot retrieve the file.") 
     (l, false) 
    } 
    } 
}) 

def isContained(message: String) = State(l => (l, l.exists(message.contains))) 

/* assume the following get or post method will be invoked when GET or POST request is sent to the endpoint */ 

def post() = update(Vector.empty) // how can I pass the updated state to the get method 

def get(msg: String): Boolean = isContained(msg)(???)._2 

Dann weiß ich nicht, wie kann ich den aktuellen Zustand auf den nächsten Besuch als Eingabe ohne var passieren.

Antwort

0

Es gibt kein kostenloses Mittagessen. Wenn Sie die Änderbarkeit vermeiden und den Status nicht irgendwo speichern möchten, müssen Sie mit zurückgegebenen Werten arbeiten.

State ist nicht mehr als eine Funktion A => B (ich es für einen Zweck, ein wenig vereinfacht), wo A Anfangszustand ist und B ist das Endresultat

Also in Ihrem Fall würde das Modell wie suchen:

def post(newMessage: String, state: List[String]): List[String] = { 
    newMessage :: state 
} 

def get(msg: String, state: List[String]): Boolean = { 
    state.contains(msg) 
} 

Wie Sie hier sehen können, müssen Sie jeden post, um den aktuellen Zustand zur Verfügung zu stellen und get. Beiträge würden nur eine neue Nachricht aus der Datei hinzufügen (setzen Sie hier Ihre Geschäftslogik ein) und einen neuen Status zurückgeben. Und für get müssen Sie den aktuellen Status bereitstellen, um etwas abrufen zu können, das Sie möchten. Sie können es so umschreiben:

def post(newMessage: String): List[String] ⇒ List[String] = state ⇒ { 
    newMessage :: state 
} 

def get(msg: String): List[String] ⇒ Boolean = 
    _.contains(msg) 

Beachten Sie, dass Sie kehrt genau A ⇒ A (wo A = List[String]) abgeben.

ScalaZ State gibt Ihnen Monade für die Funktionen im Inneren für das Verständnis Verkettungs sowie einige zusätzliche Annehmlichkeiten (wie map, gets, put etc ..). Aber im Wesentlichen - das zugrunde liegende Modell wäre das gleiche.

Dieser stellt genauer gesagt, was State tut:

type YourListState = List[String] ⇒ List[String] 

    def post(newMessage: String, state: YourListState): YourListState = li ⇒ { 
    newMessage :: state(li) 
    } 

    def get(msg: String, state: YourListState): List[String] ⇒ Boolean = { 
    state(_).contains(msg) 
    } 

Dies ermöglicht Ihnen Staaten zu kombinieren und Anfangswert zu schaffen und „laufen“, wann immer Sie wollen, nicht sicher, dass Sie das wirklich brauchen.

Verwandte Themen