2017-05-27 42 views
1
def map[B] (f: A=>B) : Option[B] 

def flatMap[B] (f: A=>Option[B]) : Option[B] 

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)))) 

這裏是異常處理中map和flatMap的定義,我有這個map2是基於map和flatMap形成的。真的很難理解map2的形成。有人可以解釋map2和map2中的角色。謝謝map2 in scala in Exeption處理

+1

這是功能編程與斯卡拉的練習嗎? –

回答

1

這是另一個解釋它的嘗試。 Option是一個Monad,它以簡化的方式可能被看作是一個通用的容器,可以保存一些值。

map是一種轉換操作,它允許您使用簡單函數對「原始」類型轉換monad中的值。

flatMapmap類似,但稍微複雜一些:它允許您使用接受「原始」值的函數轉換monad中的值,但返回相同monad的實例並仍然是結果你只會得到Monad[B]而不是Monad[Monad[B]],它將由map生成。換句話說,flatMap「變平」結果。

那麼現在你的map2做什麼?它接受2個Option monad實例和一個將「原始」對類型轉換爲單個新的「原始」類型並返回該結果類型的Option的函數。從邏輯上講,這與map類似,但要實現它,您需要一個flatMap。要致電f,您需要「解包」aobo。但monad並沒有提供一種方法來「解開」原始價值。您可能只想使用map。畢竟map2在邏輯上與它相似!然而,如果你寫

ao.map(aa => 
    bo.map(bb => f(aa,bb))) 

你可能天真地做,它不會像你所期望的那樣工作。原因是bo.map(bb => f(aa,bb))返回Option[C](記住,沒有標準的方法來「解壓」一個單子),因此你的函數傳遞給ao.map(aa => ...)返回Option[C],因此結果將是Option[Option[C]]。但這正是flatMap來救援!它允許你將這個雙重Option「解包」成簡單的Option[C]

顯然這個解釋很天真,但我希望它能幫助你對發生的事情有一個直覺。

2

如果添加使用一些語法糖for-comprehension它突然成爲了很多更容易閱讀,如果你問我:

def map2[A,B,C] (ao: Option[A], bo: Option[B])(f: (A,B) => C): Option[C] = for { 
    a <- ao 
    b <- bo 
} yield f(a,b) 

基本上,我們要提取a和我們兩國的b選項,然後應用我們的功能f獲得CflatMap允許我們這樣做,通過使用從AOption[B]的函數。 map然後允許我們應用我們的功能f來將(A,B)變換成C

+0

是的,我知道這是爲了理解,但我想知道使用flatMap和map後面的過程,因爲最終,編譯器將綁定綁定到flapMap調用,最終的綁定和yield被轉換爲map調用。對? –

+0

是的,完全'for'被desquare到'flatMap'和'map'。我不確定你的問題是什麼。你在問爲什麼要使用這兩個功能? –

+0

我在問這個問題,因爲我仍然是scala的新手。爲什麼你在()中寫出(f:(A,B)=> C)而不是其他參數。我的意思是,爲什麼它不像 - >(ao:Option [A],bo:Option [B],f:(A,B)=> C):Option [C] = ... – pythonic