2016-12-25 7 views
1
sealed trait Sum[+A, +B] { 
    def flatMap[A, C](f: B => Sum[A, C]): Sum[A, C] = 
    this match { 
     case Failure(v) => Failure(v) 
     case Success(v) => f(v) 
    } 
} 

関数のパラメータは反例であり、結果は共変ですか?なぜコンパイラはAが反対の位置にいると言うのでしょうか?私は、コンパイラが、Bが逆変わりの位置にあると不平を言うことを期待しています。関数の差異

誰かが私にこの理由を説明することはできますか?混乱していると感じる。

sealed trait Sum[+A, +B] { 
    def flatMap[C](f: B => Sum[A, C]): Sum[A, C] = // No shadowing of A 
    this match { 
     case Failure(v) => Failure(v) 
     case Success(v) => f(v) 
    } 
} 

再びflatMapを見てみましょう:

def flatMap[C](f: B => Sum[A, C]): Sum[A, C] 

するのは、それを少し書き直してみましょう:

+4

メソッド定義に 'A'型のパラメータがオーバーロードされているためですか? 'def flatMap [C](f:B => Sum [A、C]):Sum [A、C]'とするとエラーになります。 – adamwy

+1

なぜ人々がこのコメントをアップヴォートするのか分かりません。過負荷を掛けなくても、「A」*は反差異的な位置にあります。大きな説明については、このプレゼンテーションを参照してください:https://youtu.be/VZWLRepyNvo?t=1h5m57s –

+0

私は混乱のために謝罪します。元のコードスニペットはdef flatMap [A​​A>:A、C](f:B => Sum [AA、C])でした:Sum [AA、C] = ???私はコンパイルされていないバージョンを表示し、その場で編集したかったのです。 defMap [C](f:B => Sum [A、C])だったはずです:Sum [A、C] = ??? – laiboonh

答えて

4

私はあなたが実際に書くためのものと仮定し

def flatMap[C]: (B => Sum[A, C]) => Sum[A, C] 

構築しましょう内側からタイプします。

Sum[A, C] 

Aは、通常、共変位置でSumのパラメータです。

B => Sum[A, C] 

Sum[A, C]通常共変位置である関数の結果です。これらの2つが結合し、Aが共変位置にあります。

(B => Sum[A, C]) => Sum[A, C] 

B => Sum[A, C]は、関数のパラメータので、全体の事は反変な位置にあります。 Aは前に共変位置にあったので、差異は結合し、Aは現在反変的な位置にある。 Bを見ると

:通常の反変位置である機能の

B => Sum[A, C] 

パラメータ、。

(B => Sum[A, C]) => Sum[B, C] 

全体の機能は、別の関数のパラメータであるので、contravariancesは相殺とBは共変な位置に座っています。

また、素晴らしいアナロジーを描くこともできます。彼らは、正と負の数のように見える

trait Co[+A]; trait Con[-A] 

、少しだけ:共変と反変の型パラメータの定義を見てください。(あなたは少し目を細めている場合)。これは、に似ている

  • (+) * (+) = (+)
  • (+) * (-) = (-)
  • (-) * (+) = (-)
  • (-) * (-) = (+)

:さて、あなたは小学校で学んだ乗算や看板のルールを覚えています

  • Co[Co[A]] =>A
  • Con[Con[A]] =>Aは共変位置にある反変位置にある反変位置
  • Con[Co[A]] =>Aにある共変位置
  • Co[Con[A]] =>Aです。
+0

ここに間違いがありますか? "AはSumのパラメータであり、通常は共変位置であることに注意してください。 - 反則? – laiboonh

+0

申し訳ありませんが、あなたは明確にできますか? – HTNW

+0

私は関数へのパラメータが反変的な位置にあると思いましたか? – laiboonh