2016-07-28 11 views
2

私は、コレクションとマップ関数の間のドットはオプションであると思っていましたが、それ以上の話があるようです。Scala:マップ関数の前に点が必要なのはいつですか?

scala> List(1,2,3) map (_*2) 
res6: List[Int] = List(2, 4, 6) 

scala> List(1,2,3).map (_*2) 
res7: List[Int] = List(2, 4, 6) 

これは失敗します:

これは、両方のフォーマットで動作

scala> articleFiles map (file => (file \\ "contentitem").map(a => (a \ "@id").text)).flatten 
<console>:17: error: missing parameter type 
     articleFiles map (file => (file \\ "contentitem").map(a => (a \ "@id").text)).flatten 
         ^

しかし、これは動作します:

scala> articleFiles.map (file => (file \\ "contentitem").map(a => (a \ "@id").text)).flatten 
res7: scala.collection.immutable.Seq[String] = List(20761, 22798, 22799, 21167, 21438, 20770, 21480, 21906, 21907, 21923, 22766, 22771, 22794, 22800, 22803, 22804, 22818, 22819, 22820, 22821, 20456, 20771, 21337, 21542, 21590, 20768, 20775, 

注意が、最後の2例との唯一の違いはありますドットをarticleFiles.map

+1

これは、[セミコロン推論](http://stackoverflow.com/a/10313469/4496364)によって引き起こされていますが、flatten' 'を代わりにドットのスペースを使用することができ、それが動作するはずです。この構文は接尾辞表記と呼ばれ、[安全ではありません](http://docs.scala-lang.org/style/method-invocation.html)です。私はドット表記を使うほうが好きです。なぜなら、フローを読み込み、 'flatten'や' toList'などのメソッドを使う方が簡単だからです。 –

+0

'.map'ではなく' .flatten'呼び出しで問題が発生します。 –

+0

セミコロンの推論ここでは問題ではありません。どちらの場合も、必要に応じて、行末にセミコロンを付けます。 –

答えて

0

Scalaでは、演算子はメソッドであり、そのように扱うことができます。この期間をメソッドの呼び出しに使用するか、単純に演算子として使用することができます。 This is a good explanation.
最初のものが失敗し、2番目のものが失敗したのは、2番目の例が最初のものよりずっとあいまいです。コンパイラは、メソッドの呼び出しでどのような変数型が必要かを認識していますが、オペレータ呼び出しではあいまいであり(AnyValでもかまいません)、欠落しているパラメータ型がスローされます。 簡単に言えば、マップを積み重ねるときや異なる呼び出しを使用するときに、コンパイラは使用する必要がある変数の種類を決定できません。

3

あなたはとても

articleFiles map (file => (file \\ "contentitem").map(a => (a \ "@id").text)).flatten 

は明らかに動作しません

articleFiles.map((file => (file \\ "contentitem").map(a => (a \ "@id").text)).flatten) 

意味し、単鎖に.場合とない場合の呼び出しを混在させることはできません。機能はflattenメソッドを持っていないが。この特定のエラーは、匿名関数の引数型が、関数型が予期されているコンテキストで使用されているときにのみ省略できるため、このようなコンテキストではないために発生します。

+0

私はまた、作業例を追加したいと思います: 'vs map(Option.apply)flatten'(これは高度な言語機能についての警告を表示します) – dk14

+0

サフィックス表記の唯一の潜在的な問題はセミコロン推論です – dk14

3

コードに何が起こったか、特に括弧と型が推測されることを示すためのツールがいくつか追加されています。

scala> val vs = (1 to 10).toList 
vs: List[Int] = List(1, 2, 3, 4, 5, 6, 7, 8, 9, 10) 

scala> vs.map(Option.apply) 
res0: List[Option[Int]] = List(Some(1), Some(2), Some(3), Some(4), Some(5), Some(6), Some(7), Some(8), Some(9), Some(10)) 

scala> vs.map(Option.apply).flatten 
res1: List[Int] = List(1, 2, 3, 4, 5, 6, 7, 8, 9, 10) 

scala> vs map(Option.apply).flatten 
<console>:13: error: missing argument list for method apply in object Option 
Unapplied methods are only converted to functions when a function type is expected. 
You can make this conversion explicit by writing `apply _` or `apply(_)` instead of `apply`. 
     vs map(Option.apply).flatten 
        ^

scala> vs map(Option.apply(_)).flatten 
<console>:13: error: missing parameter type for expanded function ((x$1: <error>) => Option.apply(x$1)) 
     vs map(Option.apply(_)).flatten 
         ^

scala> vs map(Option.apply(_)).flatten // show 
[snip] 
     val res4 = vs.map(((x$1) => Option apply x$1).flatten) 

<console>:13: error: missing parameter type for expanded function ((x$1: <error>) => Option.apply(x$1)) 
     vs map(Option.apply(_)).flatten // show 
         ^
+0

https://issues.scala- lang.org/browse/SI-9551 –

+0

コンパイラは予想される型の関数を含む囲むコンテキストがあると言うべきです。 http://stackoverflow.com/q/38611092/1296806に似ています。 –

+1

コメントディレクティブは非常にクールですが、それは魔法のように見えます。答えに明示的に記述します。 '//'と '' show'の間のスペース) – dk14

関連する問題