2013-10-08 66 views
1

我正在學習Michael Pilquist的優秀國家monad講座here。我有兩個問題,54分鐘卡住了。Scala國家monad中的理解

  1. 如果是Option[FollowerStats],什麼是?操作?我 找不到選項三元運營商在斯卡拉2.10.2

  2. 如何進行尾發電機把更新的緩存(包括漫無遞增)回checkCache方法的State結果?返回State似乎被丟棄,對於理解似乎只得到了Option[FollowerStats]

def checkCache(u: String): State[Cache, Option[FollowerState]] = for { 
    c <- State.get[Cache] 
    ofs <- State.state { 
     c.get(u).collect { 
      case Timestamped(fs, ts) if !state(ts) => fs 
     } 
    } 
    _ <- State.put(ofs ? c.recordHit | c.recordMiss) 
} yield ofs 

試圖理解我試圖重新編寫理解,但它沒有幫助。

State.get[Cache].flatMap{ c => 
    State.state{c.get(u).collect(...)}.flatMap{ ofs => 
     State.put(ofs ? c.recordHit | c.recordMiss).map{ _ => 
      ofs 
     } 
    } 
} 

更新: 我想我已經掌握了關鍵點2個多虧了答案。我沒有意識到收益率實際上是這樣說的:從put中取出最後一個狀態s => (s,()),並用值替換Unit值類型,得到s =>(s,ofs)。我猜想關鍵在於意識到產量不是字面上的返回,而是將其翻譯爲State.map。

更新 瞭解現在的選項位。我想這個演示文稿仍然使用斯卡拉斯的含義,儘管它是派生出單態的。

+1

'Option? ... | ...'位來自隱式轉換(特別是隱式類「OptionOps」)。您可能已經處理了隱式轉換,例如由於隱式轉換爲StringOps而能夠在字符串上調用'toInt' - 這與之大致相同。 – Shadowlands

+0

在1:06:12他實際上提到了選項。應該繼續觀看,但強迫症阻止了它。 – Pengin

+0

希望下一個OCD患者能夠看到這個VID會發現這個問題,閱讀所有的評論,並知道直接跳回來觀看其他的VID! :) – Shadowlands

回答

2

首先用於三元運算符。

ofs ? c.recordHit | c.recordMiss 

是等效於:

if (ofs.isDefined) c.recordHit else c.recordMiss 

或者:

ofs.fold(c.recordMiss)(_ => c.recordHit) 

它是由Scalaz提供,作爲一個隱含類實現(OptionOps),提供了?方法Option返回一個Conditional類有一個|方法。在這種情況下,我不確定額外的簡潔是否值得混淆,但人們使用它,所以值得了解。

對於狀態更新,請考慮以下簡單的例子:

val inc: State[Int, Unit] = for { i <- get[Int]; _ <- put(i + 1) } yield() 

它可能首先看像我們「始亂終棄」的狀態,只產生單位,但inc的值實際上是整個狀態操作計算(在這種情況下,不會返回任何相關或有趣的值),包括更新。

1
  1. ?|運營商來自scalaz的布爾語法。看看here at BooleanOps。它實際上是2個函數,第一個?,然後|Conditional上。

  2. 更新後的緩存實際上是運行State操作的結果。如果您在視頻前面看,State應該被定義爲,給定一個國家行爲和初始狀態s東西,運行在(a, s2)s結果狀態作用,這是一對:(一)值計算( (在元組中表示爲a),以及(b)在執行動作之後的新狀態(表示爲s2)。

只需注意新Cache沒有實際計算,直到初始Cache運行雖然單子行動。

+0

這是'OptionOps'上的'?',而不是'BooleanOps'。 –

+0

@TravisBrown如此真實!道歉。 – gpampara