it-swarm-eu.dev

Wie entwerfen Sie Programme in Haskell oder anderen funktionalen Programmiersprachen?

Ich habe einige Erfahrung in objektorientierten Programmiersprachen wie c # oder Ruby. Ich weiß, wie man ein Programm im objektorientierten Stil entwirft, Klassen und Objekte erstellt und Beziehungen zwischen ihnen definiert. Ich kenne auch einige Designmuster.

Wie schreiben Menschen funktionale Programme? Wie fangen sie an? Gibt es Entwurfsmuster für funktionale Sprachen? Sind Methoden wie extreme Programmierung oder agile Entwicklung für funktionale Sprachen anwendbar?

52
Luke

Ich schreibe meine Antwort hauptsächlich mit Blick auf Haskell, obwohl viele Konzepte für andere funktionale Sprachen wie Erlang, LISP (s) und ML gleich gut gelten. Einige gelten sogar (teilweise) für Ruby, Python, Perl und Javascript.

Wie schreiben Menschen funktionale Programme? Wie fangen sie an?

Durch das Schreiben von Funktionen. Wenn Sie eine funktionale Programmierung durchführen, schreiben Sie entweder main oder Sie schreiben eine Hilfsfunktion. Manchmal besteht Ihr Hauptziel darin, einen Datentyp mit verschiedenen relevanten Funktionen zu schreiben, die darauf arbeiten.

Die funktionale Programmierung eignet sich sowohl für Top-Down- als auch für Bottom-Up-Ansätze. Haskell empfiehlt dringend, Ihre Programme in einer höheren Sprache zu schreiben und dann einfach die Details Ihres höheren Designs zu definieren. Siehe minimum zum Beispiel:

minimum    :: (Ord a) => [a] -> a
minimum xs =  foldl1 min xs

Die Funktion zum Finden des kleinsten Elements in einer Liste wird einfach als Durchquerung der Liste geschrieben, wobei die min-Funktion verwendet wird, um jedes Element mit dem "Akkumulator" oder dem aktuellen Mindestwert zu vergleichen.

Gibt es Entwurfsmuster für funktionale Sprachen?

Es gibt zwei Dinge, die mit "Entwurfsmustern" gleichgesetzt werden könnten, imho, Funktionen höherer Ordnung und Monaden. Sprechen wir über Ersteres. Funktionen höherer Ordnung sind Funktionen, die entweder andere Funktionen als Eingabe verwenden oder Funktionen als Ausgabe erzeugen. Jede funktionale Sprache verwendet im Allgemeinen map, filter und fold (Falte wird oft auch als "Reduzieren" bezeichnet): drei sehr grundlegende Funktionen höherer Ordnung, die a anwenden Funktion auf eine Liste auf verschiedene Arten. Diese ersetzen auf schöne Weise die Boilerplate für Schleifen. Das Weitergeben von Funktionen als Parameter ist ein äußerst starker Segen für die Programmierung. Viele "Entwurfsmuster" können einfacher erstellt werden, indem Funktionen höherer Ordnung verwendet werden, eigene erstellt werden können und die leistungsstarke Standardbibliothek genutzt werden kann, die voller nützlicher Funktionen ist.

Monaden sind das "beängstigendere" Thema. Aber sie sind nicht wirklich so beängstigend. Meine Lieblingsart, Monaden zu betrachten, besteht darin, sie so zu betrachten, dass sie eine Funktion in eine Blase einhüllen und dieser Funktion Superkräfte verleihen (die nur innerhalb der Blase funktionieren). Ich könnte es näher erläutern, aber die Welt braucht nicht wirklich eine weitere Monadenanalogie. Also gehe ich zu kurzen Beispielen über. Angenommen, ich möchte ein nicht deterministisches "Entwurfsmuster" verwenden. Ich möchte dieselbe Berechnung für verschiedene Eingaben gleichzeitig ausführen. Ich möchte nicht nur einen Eingang auswählen, sondern alle auswählen. Das wäre die Listenmonade:

allPlus2 :: [Int] -> [Int]
allPlus2 xs = do x <- xs
                 return (x + 2)

Nun, die idiomatische Art, dies auszuführen, ist tatsächlich map, aber zur Veranschaulichung können Sie sehen, wie die Listenmonade es mir ermöglichte, eine Funktion zu schreiben, die so aussieht, als würde sie mit einem Wert arbeiten, sie aber mit der Supermacht ausstatten an jedem Element in einer Liste arbeiten? Andere Supermächte sind Versagen, Zustand, Interaktion mit der "Außenwelt" und parallele Ausführung. Diese Superkräfte sind sehr mächtig, und die meisten Programmiersprachen ermöglichen es, dass Funktionen mit Superkräften überall toben. Die meisten Leute sagen, dass Haskell diese Superkräfte überhaupt nicht zulässt, aber tatsächlich enthält Haskell sie nur in Monaden, damit ihre Wirkung begrenzt und beobachtet werden kann.

tl; dr Grokking Funktionen und Monaden höherer Ordnung ist das Haskell-Äquivalent zu grokking Designmustern. Sobald Sie diese Haskell-Konzepte gelernt haben, denken Sie, dass "Entwurfsmuster" meist billige Problemumgehungen sind, um die Leistungsfähigkeit von Haskell zu simulieren.

Sind Methoden wie extreme Programmierung oder agile Entwicklung für funktionale Sprachen anwendbar?

Ich sehe nichts, was diese Managementstrategien mit einem Programmierparadigma verknüpft. Wie Phynfo sagte, ist die funktionale Programmierung praktisch zwingt Sie, eine Funktionszerlegung durchzuführen und ein großes Problem in Teilprobleme zu zerlegen, sodass Mini-Meilensteine ​​ein Kinderspiel sein sollten. Es gibt Tools wie QuickCheck und Zeno, um Eigenschaften der von Ihnen geschriebenen Funktionen zu testen oder sogar zu beweisen.

24
Dan Burton