2017-10-08 125 views
4

我不知道Scala編譯器如何使用flatMapOption的序列。爲什麼「flatMap」在Scala中使用Option類型的序列?

如果我對序列的序列使用flatMap

println(Seq(Seq(1), Seq()).flatMap(a => a)) // List(1) 

將串連所有嵌套序列,如果我的Option秒的順序使用它

同樣的情況:

println(Seq(Some(1), None).flatMap(a => a)) // List(1) 

因此flatMapOption視爲一個集合在這種情況下。問題是爲什麼這個工作?該flatMap具有以下定義:

def flatMap[B, That](f: A => GenTraversableOnce[B])(implicit bf: CanBuildFrom[Repr, B, That]): That 

含義,它預計,返回GenTraversableOnce實例的功能,但Option不繼承GenTraversableOnce。它只繼承ProductSerializable,而Product繼承Equals

在這種情況下,Scala編譯器如何在Option的序列上使用flatMap

+2

爲了增加Grzegorzs答案,這也源於這樣的事實'選項[A]'是*單子*,雖然這是由於選項平面圖上的通用簽名而模糊不清。 'Option [A]''上的'flatMap'(否則命名爲'bind')應該是:'def flatMap(f:A => Option [B]):Option [B]',這就是你在函數庫如scalaz和貓。 –

回答

4

你的觀察是正確的。在這種情況下,如果編譯器無法比擬的類型,它尋找的隱式轉換,並找到一個在Option的同伴對象:

import scala.language.implicitConversions 

/** 
    An implicit conversion that converts an option to an iterable value 
*/ 

implicit def option2Iterable[A](xo: Option[A]): Iterable[A] = xo.toList 

這使得治療Option S作爲Iterable秒。


此外,您的代碼可以使用flatten簡化:

Seq(Some(1), None).flatten 
相關問題