SORU
12 EKİM 2011, ÇARŞAMBA


Scalaz devlet monad örnekleri

Scalaz devlet monad birçok örnek görmedim. Ama bunu anlamak zor. this example var ve görünüşe göre bir tek other question yığın taşması var.

İle oynadım bir kaç örnek yayınlayacağım ama yenilerini bekleriz. Ayrıca eğer biriinit, modify, put gets harika olurdu için kullanılır neden örnek verebilir.

Edit: here harika bir 2 saat devlet monad hakkında sunum.

CEVAP
12 EKİM 2011, ÇARŞAMBA


Sanırımscalaz 7.0.xve ithalat (cevap için geçmişe bakın . aşağıdaki ^em>scalaz 6.x):

import scalaz._
import Scalaz._

Devlet bu tür S devlet tipi ve A değeri dekore edilmiş varlık türü olduğu State[S, A] olarak tanımlanır. Devlet bir değer oluşturmak için temel sözdizimi State[S, A] işlevini kullanır:

// Create a state computation incrementing the state and returning the "str" value
val s = State[Int, String](i => (i   1, "str")) 

Başlangıç değeri devlet hesaplama çalıştırmak için:

// start with state of 1, pass it to s
s.eval(1)
// returns result value "str"

// same but only retrieve the state
s.exec(1)
// 2

// get both state and value
s(1) // or s.run(1)
// (2, "str")

Devletin işlev çağrıları ile dişli olabilir. Bunu yapmak yerine, 24**, Function[A, State[S, B]]] tanımlayın. Kullanım State fonksiyonu...

import java.util.Random
def dice() = State[Random, Int](r => (r, r.nextInt(6)   1))

Sonra for/yield sözdizimi fonksiyonları oluşturmak için kullanılabilir:

def TwoDice() = for {
  r1 <- dice()
  r2 <- dice()
} yield (r1, r2)

// start with a known seed 
TwoDice().eval(new Random(1L))
// resulting value is (Int, Int) = (4,5)

Burada başka bir örnek. TwoDice() devlet hesaplamalar içeren bir liste doldurmak.

val list = List.fill(10)(TwoDice())
// List[scalaz.IndexedStateT[scalaz.Id.Id,Random,Random,(Int, Int)]]

Sıra State[Random, List[(Int,Int)]] bir almak için kullanın. Yazın bir diğer sağlayabiliriz.

type StateRandom[x] = State[Random,x]
val list2 = list.sequence[StateRandom, (Int,Int)]
// list2: StateRandom[List[(Int, Int)]] = ...
// run this computation starting with state new Random(1L)
val tenDoubleThrows2 = list2.eval(new Random(1L))
// tenDoubleThrows2  : scalaz.Id.Id[List[(Int, Int)]] =
//   List((4,5), (2,4), (3,5), (3,5), (5,5), (2,2), (2,4), (1,5), (3,1), (1,6))

Ya da bu tür anlaması sequenceU kullanabilirsiniz:

val list3 = list.sequenceU
val tenDoubleThrows3 = list3.eval(new Random(1L))
// tenDoubleThrows3  : scalaz.Id.Id[List[(Int, Int)]] = 
//   List((4,5), (2,4), (3,5), (3,5), (5,5), (2,2), (2,4), (1,5), (3,1), (1,6))

Liste yukarıdaki meblağlar frekans hesaplamak için State[Map[Int, Int], Int] ile başka bir örnek. freqSum toplamı ve frekansları atar sayıları hesaplar.

def freqSum(dice: (Int, Int)) = State[Map[Int,Int], Int]{ freq =>
  val s = dice._1   dice._2
  val tuple = s -> (freq.getOrElse(s, 0)   1)
  (freq   tuple, s)
}

Şimdi traverse tenDoubleThrows freqSum uygulamak için kullanın. traverse map(freqSum).sequence eşdeğerdir.

type StateFreq[x] = State[Map[Int,Int],x]
// only get the state
tenDoubleThrows2.copoint.traverse[StateFreq, Int](freqSum).exec(Map[Int,Int]())
// Map(10 -> 1, 6 -> 3, 9 -> 1, 7 -> 1, 8 -> 2, 4 -> 2) : scalaz.Id.Id[Map[Int,Int]]

Ya da daha doğru bir deyimle traverseU anlaması için kullanarak türleri:

tenDoubleThrows2.copoint.traverseU(freqSum).exec(Map[Int,Int]())
// Map(10 -> 1, 6 -> 3, 9 -> 1, 7 -> 1, 8 -> 2, 4 -> 2) : scalaz.Id.Id[Map[Int,Int]]

State[S, A] bir tür olduğu için* *47, tenDoubleThrows2 ad Id olarak yazılmış olmak biter unutmayın. copoint geri List bir tür çevirmek için kullanıyorum.

Kısacası, devlet işlevi, bu durumu değiştirerek dönen ve gerçek sonuç değeri istediğiniz için kullanılacak anahtar gibiYasal Uyarı: asla üretim kodu state kullanılan, sadece alışmaya çalışıyorum.

Yorum ziggystar @ilişkin ek bilgi

stateT StateFreq StateRandom kombine hesaplama gerçekleştirmek için artırılmış olabilir gösterebilir başkası olabilir kullanmaya çalışıyorum verdim. Ne buldum yerine iki devlet transformers kompozisyonu bu şekilde kombine edilebilir:

def stateBicompose[S, T, A, B](
      f: State[S, A],
      g: (A) => State[T, B]) = State[(S,T), B]{ case (s, t) =>
  val (newS, a) = f(s)
  val (newT, b) = g(a) apply t
  (newS, newT) -> b
}

g bir parametre bir fonksiyon ilk devlet transformatörün sonuç alıp devlet bir trafo dönen varlık üzerine kurulu. Daha sonra aşağıdaki gibi çalışır:

def diceAndFreqSum = stateBicompose(TwoDice, freqSum)
type St2[x] = State[(Random, Map[Int,Int]), x]
List.fill(10)(diceAndFreqSum).sequence[St2, Int].exec((new Random(1L), Map[Int,Int]()))

Bunu Paylaş:
  • Google+
  • E-Posta
Etiketler:

YORUMLAR

SPONSOR VİDEO

Rastgele Yazarlar

  • Bryan Adams

    Bryan Adams

    30 Mart 2006
  • jeffisthecoolguy

    jeffisthecoo

    17 HAZİRAN 2013
  • Trulia

    Trulia

    29 Kasım 2006