(Ich kenne Erlang nicht und ich kann Haskell nicht schreiben, aber ich denke, ich kann trotzdem antworten.)
Nun, in diesem Interview wird das Beispiel einer Bibliothek zur Erzeugung von Zufallszahlen gegeben. Hier ist eine mögliche Stateful-Schnittstelle:
# create a new RNG
var rng = RNG(seed)
# every time we call the next(ceil) method, we get a new random number
print rng.next(10)
print rng.next(10)
print rng.next(10)
Ausgabe kann sein 5 2 7
. Für jemanden, der Unveränderlichkeit mag, ist das einfach falsch! Es sollte sein 5 5 5
, weil wir die Methode für dasselbe Objekt aufgerufen haben.
Was wäre eine zustandslose Schnittstelle? Wir können die Folge von Zufallszahlen als träge bewertete Liste anzeigen, in next
der der Kopf tatsächlich abgerufen wird:
let rng = RNG(seed)
let n : rng = rng in
print n
let n : rng = rng in
print n
let n : rng in
print n
Mit einer solchen Schnittstelle können wir immer zu einem früheren Zustand zurückkehren. Wenn zwei Teile Ihres Codes auf dasselbe RNG verweisen, erhalten sie tatsächlich dieselbe Zahlenfolge. In einer funktionalen Denkweise ist dies sehr wünschenswert.
Dies in einer Stateful-Sprache umzusetzen ist nicht so kompliziert. Beispielsweise:
import scala.util.Random
import scala.collection.immutable.LinearSeq
class StatelessRNG (private val statefulRNG: Random, bound: Int) extends LinearSeq[Int] {
private lazy val next = (statefulRNG.nextInt(bound), new StatelessRNG(statefulRNG, bound))
// the rest is just there to satisfy the LinearSeq trait
override def head = next._1
override def tail = next._2
override def isEmpty = false
override def apply(i: Int): Int = throw new UnsupportedOperationException()
override def length = throw new UnsupportedOperationException()
}
// print out three nums
val rng = new StatelessRNG(new Random(), 10)
rng.take(3) foreach (n => println(n))
Wenn Sie ein bisschen syntaktischen Zucker hinzugefügt haben, damit er sich wie eine Liste anfühlt, ist das eigentlich ganz nett.