Ich versuche, einen Chat-Server mit Haskell zu entwickeln.
Es gibt viele nützliche Werkzeuge wie TChan
, TSkiplist
, forkIO
... usw., aber es stellt sich heraus, dass der meiste Code in den IO-Monaden und unsafePerformIO geschrieben wird, was sehr ineffizient klingt.
Ist es in Ordnung, dies zu tun, oder ist Haskell nicht das richtige Werkzeug für diesen Zweck?
Versuchen Sie in der Regel zuerst Code als reine Funktionen zu schreiben, ohne sich Gedanken darüber zu machen, woher die Daten stammen - nehmen Sie einfach an, dass sie da sind.
Als nächstes fügen Sie diese reine Funktionalität in IO ein, um Ihre reinen Funktionsdaten zu füttern und die Ergebnisse irgendwo zu platzieren. Es ist in Ordnung, dass es eine Menge davon in einer Chat-Anwendung gibt! Die IO-Monade ist überhaupt nicht ineffizient, Es ist nur so, dass wir lieber so viel Code behalten wie möglich, denn das ist gutes Design - Halten Sie die Daten von der IO getrennt. Eine Chat-Anwendung berechnet nicht viel mit den Daten, die es bekommt, also ist es in Ordnung, eine Menge IO-Code zu haben.
Ich denke, es ist definitiv besser, in der IO-Monade zu bleiben, als unsafePerformIO zu verwenden, weil unsafePerformIO sein Ergebnis als reine Daten darstellt. Ich könnte versucht werden, sie zu verwenden, um Konstanten aus einer Konfigurationsdatei zu bekommen, aber ich habe es nie wirklich getan, und es macht keinen Sinn, wenn Sie sowieso stark in der IO-Monade sind. Es gibt einen Grund, warum es unsicher heißt! Petr Pudlák hat gute Ratschläge in dem Kommentar unten.
Ich habe Haskells Monaden als die beschrieben beste imperative Programmiersprache in der Welt. Ich könnte Haare über diese Beschreibung spalten, aber ich stimme dem Gefühl zu, und ja, bleib bei Haskell. Haskell ist gut in der Programmierung, für die Sie es verwenden.
Immer wenn Sie bemerken, dass Sie eine lange Funktion haben, die sich in der IO-Monade befindet, lohnt es sich, innezuhalten und sich die Berechnungen anzusehen, die stattfinden. Meiner Erfahrung nach ist es (fast) immer der Fall, dass einige Nicht-IO-bezogene Dinge passieren, die keinen Zugriff auf die Eingabe-Ausgabe benötigen und in reine Funktionen eingekapselt werden können.
Dies hat den großen Vorteil, dass Sie gezwungen sind, richtige Abstraktionen und separate (reine) Algorithmen von der Eingabe / Ausgabe-Handhabung zu finden. Außerdem ist es viel einfacher, reine Funktionen zu überprüfen und zu testen.
Natürlich werden Sie diese reinen Funktionen immer noch innerhalb einiger IO a
-Funktion aufrufen (z. B. main
), aber das ist völlig in Ordnung.
der Großteil meines Codes ist in den IO-Monaden geschrieben
Das ist in Ordnung.
und unsafePerformIO
Das ist schlecht! Vermeide die Verwendung von unsafePerformIO
wie die Pest; Es sollte nur von erfahrenen Haskellern unter sehr speziellen Umständen verwendet werden.
Ist es in Ordnung, dies zu tun, oder ist Haskell nicht das richtige Werkzeug für diesen Zweck?
Es ist in Ordnung, Code in die IO-Monade zu schreiben, aber nicht OK, um unsafePerformIO
zu verwenden. Erfahren Sie stattdessen, wie Sie E / A-Aktionen mit der Monad
-Schnittstelle ( do
-Notation) zusammenstellen. Erfahren Sie, welche Signaturen für Funktionstypen den Typ IO
enthalten müssen.