2016-11-17 14 views
5

は、誰もがリストにandThenを使用する方法の例を持っていますか?私はandThenがリストのために定義されていますが、ドキュメンテーションがそれを使用する方法を示すための例を持っていないことに気づきます。はandThenリストScalaで

私の理解では、andThenのG Fそれは、関数fを実行して、関数gを実行する意味です。関数gの入力は関数fの出力である。これは正しいです?

質問1 - 私は次のコードを書いていますが、私はなぜマップを使用して同じ結果を得ることができるのかわかりません。

scala> val l = List(1,2,3,4,5) 
l: List[Int] = List(1, 2, 3, 4, 5) 

//simple function that increments value of element of list 
scala> def f(l:List[Int]):List[Int] = {l.map(x=>x-1)} 
f: (l: List[Int])List[Int] 

//function which decrements value of elements of list 
scala> def g(l:List[Int]):List[Int] = {l.map(x=>x+1)} 
g: (l: List[Int])List[Int] 

scala> val p = f _ andThen g _ 
p: List[Int] => List[Int] = <function1> 

//printing original list 
scala> l 
res75: List[Int] = List(1, 2, 3, 4, 5) 

//p works as expected. 
scala> p(l) 
res74: List[Int] = List(1, 2, 3, 4, 5) 

//but I can achieve the same with two maps. What is the point of andThen? 
scala> l.map(x=>x+1).map(x=>x-1) 
res76: List[Int] = List(1, 2, 3, 4, 5) 

誰かがなど、andThenはフィルターのような方法よりも有用である実用的な例を共有してマップすることができ、私は上記を参照してください可能性が1つの用途はandThenで、私は組み合わせで新しい関数、pは、作成することができるということです他の機能のしかし、この使い方は、ListとandThenの有用性を引き出します。

答えて

11

andThenListのための継承ツリーアップPartialFunction少数の親から継承されます。あなたは、インデックスによってその要素にアクセスするときは、PartialFunctionとしてListを使用しています。それはあなたが、リスト自体の中にそのインデックスを占めている要素への(ゼロから)インデックスから関数としてListと考えることができ、あります。 (それが1であるため)

val list = List(1, 2, 3, 4) 

我々は関数のようlistを呼び出すことができます:私たちは、リストを持っている場合は

scala> list(0) 
res5: Int = 1 

andThenは、私たちは別で1 PartialFunctionを構成することができます。たとえば、私はListを作成し、インデックスで要素にアクセスしてから、要素に2を掛けることができます。

val list2 = list.andThen(_ * 2) 

scala> list2(0) 
res7: Int = 2 

scala> list2(1) 
res8: Int = 4 

これは本質的に計算が面倒である以外は、リスト上のmapを使用するのと同じです。もちろん、viewで同じことを達成できますが、ListをちょうどPartialFunctionとして扱いたいという一般的なケースがあるかもしれません(私の頭の上から考えることはできません) 。あなたのコードで


、あなたが実際にList自体にandThenを使用していません。むしろ、mapなどに渡している関数にこの関数を使用しています。Listをおよびgに2回、f andThen gを1回マッピングして2回マッピングすると結果に違いはありません。しかし、複数回のマッピングが高価になる場合には、この構成を使用することが好ましい。 Listの場合、複数のトラバースは、リストが大きい場合に計算上高価になる可能性があります。

2

解決策l.map(x=>x+1).map(x=>x-1)では、リストを2回トラバースしています。 andThenコンビネータを使って2つの機能を構成し、リストにそれを適用する場合 、あなたは一度だけのリストをトラバース。

val h = ((x:Int) => x+1).andThen((x:Int) => x-1) 
l.map(h) //traverses it only once