Wir schreiben "Hallo Welt!" Haskell-Webanwendung (Spock)

Ich war gelangweilt vom Schreiben in Python, ich wollte etwas Ungewöhnliches. Ich beschloss, Haskell auszuprobieren. Ich kenne die Sprache nicht, wollte aber keine Konsolentrainingsprogramme wie die Berechnung der Fakultät schreiben. Nachdem ich eine ziemlich große Anzahl von Posts über Haskell und seine Anwendung im wirklichen Leben studiert hatte, wurde mir klar, dass einer der potenziellen Punkte für das Wachstum der Popularität der Sprache das Schreiben von Webanwendungen ist. Seltsamerweise gibt es unter Haskell einige Web-Frameworks . Meine Wahl fiel auf Spock , weil es nach der Beschreibung ein einfacher und schneller Rahmen für die Entwicklung ist. Ich habe einige Erfahrung mit dem Schreiben von Webanwendungen in Flask, daher hielt ich es für interessant, solche unterschiedlichen Ansätze zur Lösung ähnlicher Probleme zu vergleichen. In dem Artikel werde ich versuchen, meine detaillierteste Art des Versuchs und Irrtums in der Studie von Haskell am Beispiel der einfachsten Spock-Webanwendung anzugeben. Vielleicht ist dies nützlich für diejenigen, die bezweifeln, ob sie versuchen sollen, Haskell zu studieren, und ob es im wirklichen Leben nützlich sein wird.


Ein bisschen über Haskell und wie man es kocht


Das erste, was jeder Entwickler beim Erlernen einer neuen Sprache erwartet, ist die Auswahl und Einrichtung einer Entwicklungsumgebung. Natürlich können Sie in ein Notizbuch schreiben, aber wenn Sie mindestens Erfahrung in der Entwicklung von Produktionsprojekten haben, verursacht diese Methode Schmerzen. Übrigens ist Haskell eine ziemlich alte und gebräuchliche Sprache und unterstützt die bekanntesten Redakteure und Ideen. Mein Freund Haskellist benutzt Emacs. Ich bin an die normale IDE gewöhnt und habe das Plugin für IntelliJ installiert.


Für die Entwicklung benötigen Sie außerdem einen Stack , der jetzt Standard ist und einen Compiler, ein Paketverwaltungssystem, ein Build- und Testsystem kombiniert.


Alles sieht ziemlich freundlich aus, es gab keine Probleme mit der Installation. Für die Entwicklung verwende ich Mac OS, ich habe es nicht auf anderen Systemen getestet, aber ich vermute, dass unter Linux auch alles ohne Probleme startet.


Hallo Welt!


Vorbereitung


Wir gehen zum Tutorial und versuchen, alles gemäß den Anweisungen zu machen. Dort schlagen sie vor, zuerst ein Standardprojekt über Stack zu stack new MyLovelyProlect : stack new MyLovelyProlect . Das Standardprojekt ist ein Ordner mit drei Unterordnern: app , src , test . Es sieht ziemlich logisch aus: ein Ordner für die Hauptanwendung, einer für Zusatzfunktionen, der dritte zum Testen. Da wir "Hallo Welt!" Schreiben, benötigen wir die Ordner src und test nicht, müssen sie jedoch nicht löschen, da wir sonst andere Dateien, z. B. HelloWorld.cabal , sorgfältig bereinigen müssen.


Eigentlich der Code


Weiter im Tutorial wird vorgeschlagen, etwas Code in Main.hs zu Main.hs Wir werden es etwas vereinfachen, um es mit dem Angebot der Flasche zu vergleichen.


 {-# LANGUAGE OverloadedStrings #-} module Main where import Web.Spock import Web.Spock.Config app :: SpockM () () () () app = get root $ text "Hello World!" main :: IO () main = do cfg <- defaultSpockCfg () PCNoDatabase () let mw = spock cfg app runSpock 8080 mw 

Zum Vergleich werde ich den gleichen Code in der Flasche geben:


 from flask import Flask app = Flask(__name__) @app.route("/") def hello(): return "Hello World!" app.run() 

Durch die Anzahl der Zeilen gewinnt flask immer noch: 8 gegen 13. Aber wenn man bedenkt, dass Haskell eine statisch typisierte Sprache ist und 2 Zeilen die Typbestimmung belegen, ist der Unterschied meiner Meinung nach gering. Zumindest hat mich der obige Code nicht davon abgehalten, die Sprache weiter zu lernen.


Montage und Start


Gehen Sie als Nächstes zu HelloWorld.cabal und fügen Sie die executable HelloWorld-exe zum Abschnitt " build-depends: " hinzu build-depends: Zeile Spock >=0.13 . Im Tutorial auf der Website wird vorgeschlagen, zwei weitere Abhängigkeiten aufzunehmen, die für meine Zwecke jedoch noch nicht benötigt werden. Wenn wir jetzt versuchen, die Anwendung mit stack build --fast --pedantic , wird der folgende Fehler stack build --fast --pedantic :


 Error: While constructing the build plan, the following exceptions were encountered: In the dependencies for HelloWorld-0.1.0.0: Spock must match >=0.13, but the stack configuration has no specified version (latest matching version is 0.13.0.0) needed since HelloWorld is a build target. Some different approaches to resolving this: * Consider trying 'stack solver', which uses the cabal-install solver to attempt to find some working build configuration. This can be convenient when dealing with many complicated constraint errors, but results may be unpredictable. * Recommended action: try adding the following to your extra-deps in /Users/dkvasov/Documents/Haskell/Spock/HelloWorld/stack.yaml: Spock-0.13.0.0@sha256:8115862eb4fb84a26fb7bcd34f30acf036bd2e7c4eaf813c185c5562d138bba2 Plan construction failed. 

Es ist ziemlich klar: Stack weiß nicht, welche Version von Spock installiert werden muss, daher muss sie in die Datei stack.yaml werden. Fügen Sie dort extra-deps und versuchen Sie erneut, diese zu erstellen. Dort werden einige andere ähnliche Fehler stack.yaml , und als Ergebnis habe ich in der Datei stack.yaml Folgendes erhalten:


 extra-deps: - Spock-0.13.0.0 - Spock-core-0.13.0.0 - reroute-0.5.0.0 - stm-containers-0.2.16 - focus-0.1.5.2 

Danach sammelte sich alles. Meine Sammlungsartefakte befanden sich im .stack-work/dist/x86_64-osx/Cabal-2.4.0.1/build .


Alles begann mit dem Befehlstack stack exec HelloWorld-exe und auf localhost:8080 sah ich das Willkommen "Hallo Welt!". Es wurde kein Tamburin-Tanz benötigt.


Wir versuchen herauszufinden, was los ist.


Bisher haben wir keine spezifischen Kenntnisse der funktionalen Programmierung (FP) und der Haskell-Sprache verwendet. Wir haben den gesunden Menschenverstand und das Wissen über die Grundlagen der Entwicklung genutzt. So können Sie nicht weitermachen. Zum weiteren Verständnis müssen wir einige Dinge über AF wissen. AF ist nicht der Antipode von OOP. Diejenigen, die mit der Scala-Sprache vertraut sind, wissen, dass beide Konzepte leicht nebeneinander existieren. Der Antipode von FP ist eine zwingende Programmierung. Während das Funktionsmodell von Berechnungen auf der Zusammensetzung von Funktionen beruht, beruht das imperative Modell auf dem Prozess aufeinanderfolgender Änderungen in den Zuständen des Systems. Daraus folgt, dass in rein funktionalen Sprachen wie Haskell angenommen wird, dass die Funktionen "rein" sind, dh sie enthalten zusätzlich zum Rückgabewert keinen veränderlichen Zustand und keine "Nebenwirkungen". Dies erleichtert das Erstellen von Feature-Kompositionen. Tatsächlich legt das Erfordernis der "Reinheit" viele Einschränkungen für die Verwendung funktionaler Sprachen in der realen Welt fest. Da es jedoch Produktionsanwendungen auf Haskell gibt, können Sie in der realen Welt immer noch reine Funktionen verwenden. Schauen wir Main.hs unsere Main.hs genauer an.


Soweit ich weiß, ist die App app eine Variable vom Typ SpockM , bei der es sich um eine Monade handelt . Wenn Sie mit dem Funktionsstil der Programmierung und der Kategorietheorie nicht vertraut sind, werden Sie höchstwahrscheinlich beim ersten Mal nicht verstehen, was es ist und warum Sie es benötigen. Dies muss jedoch zumindest auf der Basisebene behandelt werden, da Monaden die Grundlage für die Anwendung der Haskell-Sprache bilden. Zu diesem Thema gibt es einige Artikel mit unterschiedlichem Detaillierungsgrad, darunter auch zu Habré. Natürlich werde ich sie nicht hierher bringen. Bisher möchte ich berücksichtigen, dass Monaden eine solche Magie sind, die es Ihnen ermöglicht, sogenannte Nebenwirkungen hervorzurufen. In unserer Anwendung gibt es eine weitere Monade: IO . Der Nebeneffekt ist die Dateneingabe / -ausgabe.


SpockM wird von vier anderen Typen parametrisiert. Sie entsprechen der Datenbankverbindung, der Sitzung, dem Status und dem Rückgabewert. Für eine leere Anwendung wird nichts davon benötigt, daher verwenden wir immer den Typ () , der als Unit bezeichnet wird. Innerhalb der app binden wir Pfade an Aktionen. In diesem Fall haben wir den Basispfad / und die Aktion gibt "Hello, world! get- .


Als nächstes erstellen wir eine Standardkonfiguration und weisen sie cfg . Erstellen Sie anschließend mithilfe der spock Funktion Middleware für die App und cfg und übertragen Sie sie zusammen mit dem gewünschten runSpock auf runSpock .


Fazit


Es ist klar, dass alles, was hier beschrieben wird, sehr einfach ist und jeder, der Englisch spricht und mit einem Gehirn ausgestattet ist, das Gleiche tun kann, indem er sich das erste Spock-Tutorial ansieht. In diesem Artikel ging es mehr darum, wie ich die Haskell-Sprache kennenlernte. Was weiter? Außerdem schlagen fast alle Lernressourcen vor, den Status zu verwenden und eine Aufgabenanwendung zu schreiben, dann die Datenbank zu verbinden und dann ... Vielleicht werde ich in Zukunft eine Fortsetzung schreiben.


Referenzen


Source: https://habr.com/ru/post/de449628/


All Articles