2

ほとんどの例とは異なり、私は関数リテラルを作成しています。スカラ関数リテラルを構成するときにアンダースコアで部分的に適用する

私が持っている:

//types 
case class Thing1(v: Double) 
case class Thing2(v: Double) 
case class Thing3(v: Double) 
type Multiplier = Double 

//functions 
val f1 = (t: Thing1, m: Multiplier) => Thing2(m * t.v) 
val f2 = (t: Thing2) => Thing3(t.v) 

私が予想したように、次のようにコンパイルされません組み合わせる機能

Thing1 => (Multiplier => Thing3) 

を取得するために、F1とF2を構成したい:

val fcomposed1 = f1.curried.andThen(f2) // does not compile 

実験によって、私は次のものがコンパイルされ、fcomposedの正しい署名があることを確認できました:

val fcomposed2 = f1.curried(_:Thing1).andThen(f2) 

私はWhat are all the uses of an underscore in Scala?と関連する可能性Why does Scala apply thunks automatically, sometimes?のようなさまざまなソースを読んだが、残念ながら私はまだステップバイステップここで何が起こっているのか、なぜそれが動作を正確に動作することはできません。

また、Iは、fcomposed2と同一に動作するために、2つの式に分離し、上記の期待しかし代わりに第二は、コンパイルされない:f1.curriedとしてf1partialが作るれ、同じ署名を返すよう

val f1partial = f1.curried(_:Thing1) 
val fcomposed3 = f1partial.andThen(f2) // does not compile - same error as fcomposed1 

が見えます私は以前のfcomposed2がどのように機能するのかさらに詳しく知りました。

誰かが両方の行動を段階的に説明できますか?

答えて

3

ここで、_はラムダ式の構文砂糖として機能しますが、期待できないレベルで動作します。

f1.curriedThing1 => Multiplier => Thing2

f1.curried(_:Thing1)型を持つ{ x: Thing1 => f1.curried(x) }と同じです。 f1.curried(x)の結果はMultiplier => Thing2型であるため、式全体の最終型はまだThing1 => Multiplier => Thing2です。したがって、関数f2(Thing2)の入力タイプが前の関数の出力(Multiplier => Thing2)と異なるため、結果(f1partial)にandThen(f2)を呼び出すことはできません。対照的に、f1.curried(_:Thing1).andThen(f2)は、{ x: Thing1 => f1.curried(x).andThen(f2) }に拡張されている。は、{ x: Thing1 => f1.curried(x).andThen(f2) }に拡張されている。 f1.curried(x)Multiplier => Thing2と入力すると評価されますので、となります。andThen(f2)と入力すると、Multiplier => Thing3となります。

val fcomposed1 = { x: Thing1 => f1.curried(x).andThen(f2) } // valid 
val fcomposed2 = { x: Thing1 => f1.curried(x) }.andThen(f2) // error 
+0

おかげで、私が読んでする必要がありますするつもりですけれども、これは答えのようになります。式全体がThing1 => Multiplier => Thing3

に評価それではおそらくそれはあなたがこれらの二つの表現の違いについて考える場合、より明らかです本当にそれを把握するために数回! PS:2番目の段落に欠落している中かっこがあります。後ろにコードブロックがあります。 – theStrawMan

+0

表現がどのように拡大するかを示す答えと、究極の違いを明確に説明する最後の2行は素晴らしい感謝です。 Scalaが2つの式(fcomposed2とfcomposed3、私の質問を参照)を別々に展開していても、それはちょっと変わっています。 – theStrawMan

+0

追加の注記:アンダースコアのラムダ式では何が起こっているのか分かり次第、部分的なアプリケーションではなく、[this](https://stackoverflow.com/questions/7673545/usage-of-in-scala-lambda -functions)と[this(https://stackoverflow.com/questions/4422016/scala-underscore-minimal-function)質問は価値のあるものです。 – theStrawMan

関連する問題