2016-12-07 31 views
1

練習13<Scala的功能性編程> simulateMachine

,官方的回答是:

def simulateMachine(inputs: List[Input]): State[Machine, (Int, Int)] = for { 
    _ <- sequence(inputs map (modify[Machine] _ compose update)) 
    s <- get 
    } yield (s.coins, s.candies) 

第二個佔位符的第二行的位置真的混淆了我,從我的角度來看,正確的答案應該是這樣的:

def simulateMachine(inputs: List[Input]): State[Machine, (Int, Int)] = for { 
    _ <- sequence(inputs map ((modify[Machine] compose update) _)) 
    s <- get 
    } yield (s.coins, s.candies) 

請幫助我理解爲什麼第一個答案是正確的,非常感謝

回答

2

modify,我相信,是一些已知的方法,所以佔位只是在方法的eta expansion,在modify[Machine] compose update將其轉換爲Function1和使用它的方法,如compose

因此,沒有佔位符啓用modify[Machine]後可能會有有時編譯錯誤。但是,如果沒有,那麼沒有必要充分表達後佔位要麼,因爲它保證了compose這一結果是Function1,可能是用作參數map

0

這裏的問題實際上是如何組成作品: 「撰寫使得對構成其他函數f(G(X))的新功能」, ˚F撰寫克可被翻譯成:「執行F G後」

scala> val fComposeG = f _ compose g _ 
fComposeG: (String) => java.lang.String = <function> 

組合物返回它接受另一個功能一個輸入並返回一個新的國家[A,S]。

編譯器可以讓你做出這樣的事情:

val ll = inputs map update 

現在L1是列表[機=>機器]這正是更新功能需求。修改後it's必要下劃線,否則編譯器警告「的方法缺少參數列表修改......」

0

modify是一種方法,我們必須把它轉換成一個功能能夠使用compose。我們在scala中執行此操作的方式是使用佔位符語法或使用eta expansion

modify[Machine] _)相當於(f => modify[Machine](f)

所以另一種方式來寫是這樣的:

def modifyFunction: ((Machine => Machine)) => State[Machine, Unit] = f => modify[Machine](f) 

def simulateMachine(inputs: List[Input]): State[Machine, (Int, Int)] = for { 
    _ <- sequence(inputs map (modifyFunction compose update)) 
    s <- get 
} yield (s.coins, s.candies)