Option 用于處理 Scala 中的偏性,但我們也可以將普通函式提升到 Options 的背景關系中以處理錯誤。在實作函式 map2 時,我很好奇如何知道何時使用哪些函式。考慮以下實作:
def map2[A,B,C] (ao: Option[A], bo: Option[B]) (f: (A,B) => C): Option[C] =
ao flatMap {aa =>
bo map {bb =>
f(aa, bb)
aa 屬于 A 型別,而 bb 屬于 B 型別,然后將其饋送到 F,給我們一個 C。但是,如果我們執行以下操作:
def map2_1[A,B,C] (ao: Option[A], bo: Option[B]) (f: (A,B) => C): Option[C] =
ao flatMap {aa =>
bo flatMap {bb =>
f(aa, bb)
aa 仍然是 A 型別,而 bb 仍然是 B 型別,但是我們必須將最后一次呼叫包裝在 Some(f(aa, bb)) 中才能獲得 Option[C] 而不是常規 C。 為什么這是?這里在 BO 上展平是什么意思?
最后同樣重要的是,可以做更簡單的事情:
def map2_2[A,B,C] (ao: Option[A], bo: Option[B]) (f: (A,B) => C): Option[C] = for {
as <- ao
bs <- bo
} yield(f(as,bs))
我知道 for-comprehensions 是 ForEach'es、maps 和 flatmaps 等的語法糖,但是作為開發人員,我如何知道編譯器會選擇帶有 bs <- bo 的 MAP,而不是 flatMap?
我想我即將理解差異,但嵌套的平面地圖讓我感到困惑。
uj5u.com熱心網友回復:
首先考慮最后一個問題,開發人員知道編譯器將做什么,for因為行為是已定義且可預測的:除了最后一個之外,所有都<-變成了,或者取決于是否存在.flatMapmapforeachyield
map更廣泛的問題似乎是關于和之間的區別flatMap。簽名的區別應該很明顯,例如List這些是(簡化的)簽名:
def map[B] (f: A => B) : List[B]
def flatMap[B](f: A => List[B]): List[B]
因此map,只需將 a 中的值替換為List新值,將其應用于f型別的每個元素A即可生成 a B。
flatMapf通過連接呼叫原始的每個元素的結果來生成一個新串列List。它相當于map后面跟著flatten(因此得名)。
直觀地說,map是一對一的替換,而flatMap允許原始元素中的每個元素List生成 0 個或多個新元素。
轉載請註明出處,本文鏈接:https://www.uj5u.com/shujuku/444245.html
標籤:斯卡拉
上一篇:選擇日期間隔
下一篇:在Scala2中合并2個元組
