でジョン・ヒューズとのインタビュー彼はアーランとHaskellの語る、彼はErlangでステートフルなライブラリを使用することについて言うために、以下があります。
ステートフルライブラリを使用する場合は、通常、その上に副作用のないインターフェイスを構築し、残りのコードで安全に使用できるようにします。
これはどういう意味ですか?私はこれがどのように見えるかの例を考えようとしていますが、私の想像力や知識は私に失敗しています。
でジョン・ヒューズとのインタビュー彼はアーランとHaskellの語る、彼はErlangでステートフルなライブラリを使用することについて言うために、以下があります。
ステートフルライブラリを使用する場合は、通常、その上に副作用のないインターフェイスを構築し、残りのコードで安全に使用できるようにします。
これはどういう意味ですか?私はこれがどのように見えるかの例を考えようとしていますが、私の想像力や知識は私に失敗しています。
回答:
(私はErlangを知らず、Haskellを書くことはできませんが、それでも答えられると思います)
さて、そのインタビューでは、乱数生成ライブラリの例を示しています。次に、可能なステートフルインターフェイスを示します。
# 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)
出力される可能性があります5 2 7
。不変性が好きな人にとって、これは明らかに間違っています!5 5 5
同じオブジェクトでメソッドを呼び出したため、である必要があります。
それでは、ステートレスインターフェイスはどうなるでしょうか?ランダムに評価されたリストとして乱数のシーケンスを見ることができ、next
実際に頭を取得します:
let rng = RNG(seed)
let n : rng = rng in
print n
let n : rng = rng in
print n
let n : rng in
print n
このようなインターフェイスを使用すると、いつでも以前の状態に戻すことができます。コードの2つの部分が同じRNGを参照している場合、実際には同じ番号のシーケンスが取得されます。機能的な考え方では、これは非常に望ましいことです。
これをステートフル言語で実装するのはそれほど複雑ではありません。例えば:
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))
リストのように感じられるように少しの構文糖を追加すると、これは実際には非常に便利です。
ここでの重要な概念は外部の可変状態のものです。外部で変更可能な状態を持たないライブラリは、副作用がないライブラリです。このようなライブラリのすべての関数は、渡される引数にのみ依存します。
私が使用する便利なリトマス試験: