2016-03-30 5 views
2

Was ist die genaue Definition der reinen Funktion in Scala? Pure Funktion hat eine Definition, auf Wiki https://en.wikipedia.org/wiki/Pure_function. Ich denke, diese Definition ist für eine reine funktionale Programmiersprache.Pure-Funktion in Scala im Zusammenhang mit Klassenmethoden und Verschlüsse

Aber ich denke, es wird im Zusammenhang mit Klassenmethode und Schließung kompliziert.

class Ave(val a: Int, val b: Int) { 
    def ave = (a+b)/2 
} 

Ist eine reine Funktion? Ich denke es ist, weil es keine Nebenwirkung hat und es nur vom unveränderlichen Zustand der Klasse abhängt. Dies verletzt jedoch die reine Funktionsdefinition im Wiki, die besagt, dass die reine Funktion generell nicht auf nicht-lokale Variablen zugreifen soll.

ähnliche Frage auf Schließung:

def fcn(a:Int, b: Int): Unit = { 
    def ave = (a+b)/2 
} 

Für uns sind beid ave reine Funktion und entsprechen eine "val" (Unified Access-Prinzip).

Aber wie rigoros zu rechtfertigen? Wenn die Felder a und b veränderbar sind, ist ave nicht mehr rein funktional.

class Ave2(var a: Int, var b: Int) { 
    def ave = (a+b)/2 // Not pure functional 
} 

Eine andere Definition der reinen Funktion von "Funktionsprogrammierung in Scala" Buch kommen:

Ein Ausdruck e referentiell transparent ist, kann, wenn für alle Programme p, alle Vorkommen von e in p sein ersetzt durch das Ergebnis der Auswertung e ohne die Bedeutung von p zu beeinflussen. Eine Funktion f ist reiner, wenn das Ausdruck f (x) für alle referenziell transparent x

dann ist die Frage referenziell transparent ist, für eine Klasse ist ein veränderlicher Zustand in einer Klasse referenziell transparent (var a, var b in meinem Beispiel)? (Wenn ja, wird die Ave-Methode in Ave2 zur reinen Funktion, die ein Widerspruch ist)

Was ist die genaue Definition einer reinen Funktion in Scala?

Antwort

4

Kurze Antwort:
Verschlüsse nicht verhindern Reinheit solange die geschlossenen über Variablen unveränderlich sind.

Lange Antwort:
in einer wirklich funktionale Programmiersprache nicht-lokale Variablen wird sich nie ändern, so einen Verschluss mit einer Reinheit nicht beeinflusst. Haskell-Funktionen sind rein und dennoch verwendet Haskell Verschlüsse ohne Probleme. Solange Ihre Funktion der Regel folgt, keine Nebenwirkungen zu haben und jedes Mal, wenn sie aufgerufen wird, dasselbe Ergebnis für denselben Satz von Parametern zu erhalten (mit anderen Worten, keinen veränderlichen Zustand zu haben), erhalten Sie die referentielle Transparenz und somit Reinheit. Wenn Sie sich mit der theoretischen Sicht auf Dinge beschäftigen, dann verstehe ich völlig, dass Sie sich Sorgen um Schließungen machen müssen, da reine Funktionen nur von ihren Argumenten und ihren Argumenten abhängen sollten (nicht notwendigerweise von allen). Aus praktischer Sicht wird das Schließen unveränderlicher Variablen jedoch nicht als Verletzung der Reinheit betrachtet.

Beachten Sie, dass der lokal veränderbare Zustand auch nicht unbedingt die Reinheit gefährdet.Das ist ein rutschiges Terrain, aber Martin Odersky hat sich einmal selbst gesagt (ich kann die genaue Quelle ausgraben, wenn ich wirklich muss, es war entweder ein Vortrag über einen der Coursera-Kurse oder das Buch Programming in Scala), dass Vars so lange okay sind du hältst sie für die Außenwelt unsichtbar. Also diese dumme Funktion:

def addOne(i: Int) = { 
    var s = i 
    s = s + 1 
    s 
} 

rein betrachtet werden kann, obwohl es wandelbar Zustand verwendet (variable s), weil der wandelbare Zustand ist nicht auf die „Außenwelt“ ausgesetzt und nicht die referentielle Transparenz der Methode nicht setzen addOne in Gefahr.

+0

Danke für die Antwort! Ich denke, das spricht von der Schließung Teil, was ist mit der Methode, wie die Klasse Ave oben? Gilt die gleiche Regel? Hat Haskell das Konzept von Klasse und Methode? – szli

+0

Ja, das Gleiche gilt. Warum nicht? In diesem Fall ist 'ave' eine Methode, keine Funktion, daher kann nicht erwartet werden, dass sie dieselben Ergebnisse liefert, wenn sie auf verschiedenen Objekten aufgerufen wird. Aber Aufrufe desselben Objekts führen immer zum selben Ergebnis. Was die Haskell betrifft, nein, es gibt dort keine klassischen OOP-Konzepte. Es gibt Typklassen, aber das ist etwas anderes (zwischenzeitlich können Sie auch Typklassen in Scala mit parametrisierten Eigenschaften und impliziten Implementierungen für verschiedene Typen modellieren, aber das ist off-topic). – slouc

Verwandte Themen