簡體   English   中英

類似於功能 Scala 中的 for-loop

[英]Similar to for-loop in functional Scala

我想創建一個模擬 model 來學習 Scala 以及函數式編程(FP)。 我已經有了所有的邏輯:創建一組代理(它只是一個List[Agent] ,其中Agent是一個 class 定義一個單獨的成員,就像氣體中的粒子)和一些功能(例如在太空中移動)對人口的“行動”。

由於 FP 中的不變性,當我想在初始總體上多次應用相同的函數時,我的問題就出現了。 我想將這些函數應用於 N 輪的初始總體(在應用所有函數后定義一輪)。 我不知道如何處理輪次之間的不可變值。

通常,我會做一個 for 循環,其中一個變量會改變它的值,但是當值是不可變的時,你如何處理呢?

我的代碼現在看起來像這樣:

object Main extends App {
    val soc = Society(numAgents = 1000)        // Create a Society

    val agents = soc.initSociety()             // Init the society
    val movedAgents = soc.moveAgents(agents)   // Move the agents
}

該方法被定義為返回List[Agent] ,因此類型始終相同。

我見過一些使用foldleft的解決方案,但我需要將 function moveAgents 應用於它返回的內容。

您可以通過折疊獲得moveAgents的返回值。 如果你只是想調用moveAgents方法n次,你可以這樣做

val newAgents = (1 to n).foldLeft(soc.initSociety()) { (a, i) => soc.moveAgents(a) }

這相當於在調用moveAgents時執行 soc.moveAgents(soc.moveAgents( n soc.moveAgents(soc.moveAgents(...(soc.initSociety())))

如果您有多個要應用的功能(每輪使用不同的功能),您可以執行相同的操作:

// n/3 because there are 3 functions
val newAgents = (1 to n/3).foldLeft(soc.initSociety()) { (a, i) => f3(f2(f1(a))) }

如果你有一個函數List ,你可以試試這個:

val fs = List(f1, f2, f3)
val newAgents = (1 to (n/fs.size)).foldLeft(soc.initSociety()){ (a, i) => fs.foldLeft(a){ (ag, f) => f(ag) } }

好吧,任何簡單的 for 循環都可以很容易地重寫為 tal 遞歸,而(尾)遞歸通常可以寫為foldLeft

第一種方法,簡單循環。

def stimulate(soc: Society, n: Int): List[Agent] = {
  var agents = soc.initSociety()
  for (i <- 0 to n) {
    agents = soc.moveAgents(agents)
  }
  agents
}

第二種方法,遞歸。
(讓我們刪除那個var)

def stimulate(soc: Society, n: Int): List[Agent] = {
  @annotation.tailrec
  def loop(i: Int, agents: List[Agent]): List[Agent] =
    if (i < n) loop(i + 1, agents = soc.moveAgents(agents))
    else agents

  loop(i = 0, agents = soc.initSociety())
}

第三種方法,折疊。
(讓我們從遞歸中刪除樣板)

def stimulate(soc: Society, n: Int): List[Agent] =
  (0 to n).foldLeft(soc.initSociety()) { case (agents, _) =>
    soc.moveAgents(agents)
  }

如果每輪之間的中間值有任何興趣......

val rounds = List.iterate(agents, n)(f _ andThen g andThen h)

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM