2013-03-10 7 views
7

は、Exception.allCatch一部のScalaメソッドで、Any/Nothingを使用する代わりに多態的な引数を使用するのはなぜですか?例えば

def allCatch[T]: Catch[T] 

として定義されているのはなぜだけではなく、

val allCatch: Catch[Nothing] 

Catchは、その引数で共変です

あるいは、なぜPartialFunctionオブジェクトが

def empty[A, B]: PartialFunction[A, B] 

だけではなく

val empty: PartialFunction[Any,Nothing] 

を定義しますか?

更新:これまでのところ、回答が不足しているようです。だから、実際に質問を対象とする具体的な例を回答に含めてください。例:def empty[A, B]: PartialFunction[A, B]で動作するコードを表示しますが、val empty: PartialFunction[Any,Nothing]では動作しません(あまり便利ではありません)。

+0

あなたの質問を更新して、それが重要な理由を含めるべきだと思います。 – nilskp

+0

@nilskp私はライブラリのデザインが好きです。特に、私自身のコードを作成するときには、多態的なバリアントか 'Any/Nothing'を持つバリアントを使うべきですか? –

答えて

2

これにより、後でキャストする必要がなくなり、通常はより便利なAnyの代わりにargsタイプをTとして扱うことができます。ここで

は一例です:

scala> def func1[T](arg : T) : T = { arg } 
func1: [T](arg : T)T 

scala> def func2(arg : Any) : Any = { arg } 
func2: (arg: Any)Any 

scala> func1(4) 
res4: Int = 4 

scala> func2(4) 
res7: Any = 4 
+1

あなたの例は正しいですが、疑いはありませんが、私の質問には答えません。それは不変型のパラメータを含んでいます - それを 'def func1 [T]:T => T =(arg:T)=> arg'と言い換えることができます。ここではもちろん、型パラメータを避けることはできません。そのような試みがあれば、その関数はあまり一般的ではありません。しかし、私の質問は、co(ntra)バリアント型パラメータを持つ型を対象としています。おそらく、私が質問した例を直接扱います。 –

2

あなたはハードコードタイプは、PartialFunction[Any,Nothing]のように、あなたがAnyよりも多くの特定のパラメータを取るためにあなたの機能を制限することができない場合。

汎用タイプのパラメータを使用すると、すべてのケースをより柔軟に満たすことができ、特にその機能を安全にすることができます。

Animalをパラメータとし、Integerを返すことを目的とした関数が必要であるとします。

はのは、その関数が存在として宣言されていると仮定しましょう:

def myFunction: PartialFunction[Any,Nothing] 

まず、部分写像は、パラメータ側ではなくAnyAnimalに特化したことではないでしょう。私がパラメータとしてHumanを渡すとどうなるでしょう...、それは通過するでしょう..安全はどうですか?

第2に、この関数がNothingを返すと宣言されている場合は、Nothing!を返すことはできません!実際、NothingはScalaのすべてのクラスをサブクラス化しています。 Nothingではなく、関数を面白くするために、戻り型パラメータは常に共変でなければならないという既知のルールが導かれます。

の方法を扱っている場合にのみ、Nothingが興味深いのは、PartialFunctionです。論理PartialFunctionの定義からは何も返されず、それを強制する必要があります:)

あなたは質問します。「なぜ戻り値の型をAnyに変更しないのですか?" 答え:ジェネリック消去時間のすべての利点を失うため、コンパイラは必要なキャストを自動的に追加します=>あなたはInteger値を直接取得することはありませんが、Anyを迷惑にします。

+0

あなたの答えを詳述して、いくつかの例を挙げてください。 –

+0

詳細な説明で更新されました。 – Mik378

+2

まだ私の質問には答えられないと感じます。もちろん、何かを 'PartialFunction [Any、Nothing]'として宣言する意味はありません。しかし、それは私が求めていたものではありませんでした。私の質問は、なぜこのタイプの単一の空の関数を宣言しないのですか?入力を読み取ることはなく、決して値を返しません。したがって、その型の[Any、Nothing]は完全に安全です。さらに、co(ntra)分散のために、それは任意の 'A 'および' B'のために '[A、B]'型に自動的にキャストされます。 –

2

PartialFunctionavailable here我々はそれが実際にPartialFunctionオブジェクトのプライベートメソッドを呼び出すことがわかります。

private[this] val empty_pf: PartialFunction[Any, Nothing]

だから、空の戻り値の型は常にPartialFunction[Any, Nothing]になります私は見当がつかないの背後にある理由については多分誰か。それ以外の理由については、より良い洞察を得ることができます。 geメーリングリストも...

1

実際、Scalaの標準ライブラリには、ジェネリック型のパラメータが冗長な場所がいくつかあります(型の違いにより)。たとえば、私のquestionforeachを参照してください。 @ Peterの回答に基づく私の推測は、これらの冗長ジェネリックがインターフェイスをより明確にするということです。これらのおかげで、どの型が共変、反変、不変であるかを覚える必要はありません。また、これは、分散に精通していない人にとっては、Scalaの高度な機能であるため、より簡単になります。

+0

ありがとう、 'foreach'は別の良い例です。 –

関連する問題