【函數(shù)式】Monads模式初探——Option Monad

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)入我的博客主頁

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

推薦閱讀更多精彩內(nèi)容

  • Monads 帶有map和flatMap方法的數(shù)據(jù)結(jié)構(gòu)很常見。實(shí)際上,there’s a name that de...
    pangolulu閱讀 792評論 0 3
  • lang 2.1.和Java的異同 2.1.1.語法 Java++:增加的語法 -》純OO;操作符重載;closu...
    時(shí)待吾閱讀 2,411評論 0 0
  • NAME dnsmasq - A lightweight DHCP and caching DNS server....
    ximitc閱讀 2,936評論 0 0
  • 生活不缺難過,哭過痛過就要跟堅(jiān)強(qiáng)的活著—題記 在媽媽的建議下,剛剛看完了一部電影—《摔跤吧爸爸》 馬哈維亞一直想要...
    雯忻閱讀 394評論 0 0
  • 溫暖的人心底一直都是溫和善良的,無論是怎樣的形式,心底總是炙熱的,外人看不來的,才是屬于我們自己的柔軟。
    _木木mumu閱讀 215評論 0 1