第七色在线视频,2021少妇久久久久久久久久,亚洲欧洲精品成人久久av18,亚洲国产精品特色大片观看完整版,孙宇晨将参加特朗普的晚宴

為了賬號(hào)安全,請(qǐng)及時(shí)綁定郵箱和手機(jī)立即綁定
已解決430363個(gè)問(wèn)題,去搜搜看,總會(huì)有你想問(wèn)的

更新嵌套結(jié)構(gòu)的更清潔方法

更新嵌套結(jié)構(gòu)的更清潔方法

更新嵌套結(jié)構(gòu)的更清潔方法說(shuō)我有以下兩個(gè)case classes:case class Address(street: String, city: String, state: String, zipCode: Int)case class Person(firstName: String, lastName: String, address: Address)和以下Person類的實(shí)例:val raj = Person("Raj", "Shekhar", Address("M Gandhi Marg",                                            "Mumbai",                                            "Maharashtra",                                            411342))現(xiàn)在,如果我想更新zipCode,raj那么我將不得不做:val updatedRaj = raj.copy(address = raj.address.copy(zipCode = raj.address.zipCode + 1))隨著嵌套水平的提高,這將變得更加丑陋。是否有更清潔的方式(像Clojure的東西update-in)來(lái)更新這樣的嵌套結(jié)構(gòu)?
查看完整描述

3 回答

?
MYYA

TA貢獻(xiàn)1868條經(jīng)驗(yàn) 獲得超4個(gè)贊

拉鏈

Huet的Zipper為不可變數(shù)據(jù)結(jié)構(gòu)提供了方便的遍歷和“變異”。Scalaz為Streamscalaz.Zipper)和Treescalaz.TreeLoc)提供Zippers 。事實(shí)證明,拉鏈的結(jié)構(gòu)可以自動(dòng)地從原始數(shù)據(jù)結(jié)構(gòu)中導(dǎo)出,其方式類似于代數(shù)表達(dá)式的符號(hào)區(qū)分。

但是,這對(duì)您的Scala案例類有何幫助?好吧,Lukas Rytz最近制作了一個(gè)scalac擴(kuò)展原型,可以自動(dòng)為帶注釋的案例類創(chuàng)建拉鏈。我將在這里重現(xiàn)他的例子:

scala> @zip case class Pacman(lives: Int = 3, superMode: Boolean = false) 

scala> @zip case class Game(state: String = "pause", pacman: Pacman = Pacman()) 

scala> val g = Game() 

g: Game = Game("pause",Pacman(3,false))


// Changing the game state to "run" is simple using the copy method:

scala> val g1 = g.copy(state = "run") 

g1: Game = Game("run",Pacman(3,false))


// However, changing pacman's super mode is much more cumbersome (and it gets worse for deeper structures):

scala> val g2 = g1.copy(pacman = g1.pacman.copy(superMode = true))

g2: Game = Game("run",Pacman(3,true))


// Using the compiler-generated location classes this gets much easier: 

scala> val g3 = g1.loc.pacman.superMode set true

g3: Game = Game("run",Pacman(3,true)

因此,社區(qū)需要說(shuō)服Scala團(tuán)隊(duì),這項(xiàng)工作應(yīng)該繼續(xù)并集成到編譯器中。


順便提一下,Lukas最近發(fā)布了Pacman版本,用戶可以通過(guò)DSL進(jìn)行編程。但是,看起來(lái)他沒(méi)有使用修改過(guò)的編譯器,因?yàn)槲铱床坏饺魏蜙zip注釋。


樹重寫

在其他情況下,您可能希望在整個(gè)數(shù)據(jù)結(jié)構(gòu)中應(yīng)用一些轉(zhuǎn)換,根據(jù)某種策略(自上而下,自下而上),并基于與結(jié)構(gòu)中某個(gè)點(diǎn)的值匹配的規(guī)則。經(jīng)典的例子是為一種語(yǔ)言轉(zhuǎn)換AST,也許是為了評(píng)估,簡(jiǎn)化或收集信息。Kiama支持重寫,請(qǐng)參閱RewriterTests中的示例,并觀看此視頻。這是一個(gè)激發(fā)你胃口的片段:


// Test expression

val e = Mul (Num (1), Add (Sub (Var ("hello"), Num (2)), Var ("harold")))


// Increment every double

val incint = everywheretd (rule { case d : Double => d + 1 })

val r1 = Mul (Num (2), Add (Sub (Var ("hello"), Num (3)), Var ("harold")))

expect (r1) (rewrite (incint) (e))

請(qǐng)注意,Kiama會(huì)在類型系統(tǒng)之外執(zhí)行此操作。


查看完整回答
反對(duì) 回復(fù) 2019-08-15
?
守候你守候我

TA貢獻(xiàn)1802條經(jīng)驗(yàn) 獲得超10個(gè)贊

有趣的是,沒(méi)有人添加鏡頭,因?yàn)樗麄兪菫檫@種東西制作的。所以,這里有一篇CS背景文件,這里有一篇博客,簡(jiǎn)要介紹了Scala中使用的鏡頭,這里是Scalaz的鏡頭實(shí)現(xiàn),這里有一些使用它的代碼,看起來(lái)非常像你的問(wèn)題。而且,為了減少鍋爐板,這是一個(gè)為案例類生成Scalaz鏡頭的插件。


對(duì)于獎(jiǎng)勵(lì)積分,這是另一個(gè)涉及鏡頭的SO問(wèn)題,以及Tony Morris 的論文。


鏡頭的重要性在于它們是可組合的。所以一開始它們有點(diǎn)麻煩,但是你使用它們的次數(shù)越來(lái)越多。此外,它們非常適合測(cè)試,因?yàn)槟恍枰獪y(cè)試單個(gè)鏡頭,并且可以理所當(dāng)然地將它們的成分視為理所當(dāng)然。


因此,根據(jù)本答案末尾提供的實(shí)現(xiàn),以下是您使用鏡頭的方法。首先,聲明鏡頭以更改地址中的郵政編碼和人員中的地址:


val addressZipCodeLens = Lens(

    get = (_: Address).zipCode,

    set = (addr: Address, zipCode: Int) => addr.copy(zipCode = zipCode))


val personAddressLens = Lens(

    get = (_: Person).address, 

    set = (p: Person, addr: Address) => p.copy(address = addr))

現(xiàn)在,組合它們以獲得一個(gè)改變一個(gè)人的zipcode的鏡頭:


val personZipCodeLens = personAddressLens andThen addressZipCodeLens

最后,使用那個(gè)鏡頭來(lái)改變r(jià)aj:


val updatedRaj = personZipCodeLens.set(raj, personZipCodeLens.get(raj) + 1)

或者,使用一些語(yǔ)法糖:


val updatedRaj = personZipCodeLens.set(raj, personZipCodeLens(raj) + 1)

甚至:


val updatedRaj = personZipCodeLens.mod(raj, zip => zip + 1)

以下是從Scalaz中獲取的簡(jiǎn)單實(shí)現(xiàn),用于此示例:


case class Lens[A,B](get: A => B, set: (A,B) => A) extends Function1[A,B] with Immutable {

  def apply(whole: A): B   = get(whole)

  def updated(whole: A, part: B): A = set(whole, part) // like on immutable maps

  def mod(a: A, f: B => B) = set(a, f(this(a)))

  def compose[C](that: Lens[C,A]) = Lens[C,B](

    c => this(that(c)),

    (c, b) => that.mod(c, set(_, b))

  )

  def andThen[C](that: Lens[B,C]) = that compose this

}


查看完整回答
反對(duì) 回復(fù) 2019-08-15
  • 3 回答
  • 0 關(guān)注
  • 474 瀏覽
慕課專欄
更多

添加回答

舉報(bào)

0/150
提交
取消
微信客服

購(gòu)課補(bǔ)貼
聯(lián)系客服咨詢優(yōu)惠詳情

幫助反饋 APP下載

慕課網(wǎng)APP
您的移動(dòng)學(xué)習(xí)伙伴

公眾號(hào)

掃描二維碼
關(guān)注慕課網(wǎng)微信公眾號(hào)