Option Monad
Scala中的Option是一個(gè)Monad實(shí)現(xiàn)。
Option的簡化版定義如下:
sealed abstract class Option[+A] {
def isEmpty: Boolean
def get: A
def map[B](f: A => B): Option[B] =
if(isEmpty) None else Some(f(this.get))
def flatMap[B](f: A => Option[B]): Option[B] =
if(isEmpty) None else f(this.get)
}
final case class Some[+A](x: A) extends Option[A] {
def isEmpty: false
def get = x
}
final case class None extends Option[Nothing] {
def isEmpty = true
def get = throw new NoSuchElementException("None.get")
}
代碼中,Option定義了flatMap,Some和None都被定義為case class,所以其名字就是構(gòu)造器,無需定義unit函數(shù)。
Option可以看成是只有一個(gè)元素的容器:
- map的工作就是對僅有的一個(gè)元素進(jìn)行f調(diào)用,然后將結(jié)果打包成Option
- flatMap的工作是對一個(gè)元素進(jìn)行f調(diào)用,產(chǎn)生的結(jié)果已經(jīng)是Option實(shí)例,并且沒有其他的結(jié)果需要flatten
None的存在是唯一的插曲,map和flatMap對于None要做的額外工作就是檢查自己是不是None,如果是,則直接返回None。因?yàn)镹one表示一個(gè)空的容器,因此不能進(jìn)行其他的計(jì)算。
用Monad規(guī)則驗(yàn)證Option
對于Option,unit(x) == Some(x)。下面是Option的flatMap構(gòu)造:
def flatMap[U](f: T => Option[U]): Option[U] = this match {
case Some(x) => f(x)
case None => None
}
我們先證明Some(x) flatMap f == f(x)
:
Some(x) flatMap f
== Some(x) match {
case Some(x) => f(x)
case None => None
}
== f(x)
然后我們證明opt flatMap Some == opt
:
opt flatMap Some
== opt match {
case Some(x) => Some(x)
case None => None
}
== opt
這里,我們看到對一個(gè)Option對象opt進(jìn)行flatMap操作,
其中映射函數(shù)式Some構(gòu)造函數(shù)時(shí),返回的是初始時(shí)的opt
我們還要證明opt flatMap f flatMap g == opt flatMap (x => f(x) flatMap g)
:
opt flatMap f flatMap g
== opt match { case Some(x) => f(x) case None => None}
match { case Some(y) => g(y) case None => None}
如果將第二個(gè)match表達(dá)式嵌入第一個(gè)match表達(dá)式中,將得到
== opt match {
case Some(x) =>
f(x) match {case Some(y) => g(y) case None => None}
case None =>
None match {case Some(y) => g(y) case None => None}
}
== opt match {
case Some(x) =>
f(x) match {case Some(y) => g(y) case None => None}
case None => None
}
== opt match {
case Some(x) => f(x) flatMap g
case None => None
}
== opt flatMap (x => f(x) flatMap g)
轉(zhuǎn)載請注明作者Jason Ding及其出處
jasonding.top
Github博客主頁(http://blog.jasonding.top/)
CSDN博客(http://blog.csdn.net/jasonding1354)
簡書主頁(http://www.lxweimin.com/users/2bd9b48f6ea8/latest_articles)
Google搜索jasonding1354進(jìn)入我的博客主頁