5

重複の可能性:
タイプの違いを強制する

scala には等価性を強制する一般化された型制約が=:=あるため、型に対して「等しくない」ことを強制するものはありますか? 基本的!=には型用?

編集

以下のコメントは既存のQ&Aを示しており、答えは (1) いいえ、標準ライブラリにはありません (2) はい、定義することは可能です。

ですから、答えを見た後に思いついたので、質問を変更します。

既存のソリューションを考えると:

sealed class =!=[A,B]

trait LowerPriorityImplicits {
  implicit def equal[A]: =!=[A, A] = sys.error("should not be called")
}
object =!= extends LowerPriorityImplicits {
  implicit def nequal[A,B](implicit same: A =:= B = null): =!=[A,B] = 
    if (same != null) sys.error("should not be called explicitly with same type")
    else new =!=[A,B]
}     

case class Foo[A,B](a: A, b: B)(implicit e: A =!= B)

A <: Bまたはの場合A >: B、それはまだそうA =!= Bですか?A =!= Bそうでない場合、そうでない場合、またはそうでない場合に解決策を変更することは可能ですA <: BA >: B?

4

1 に答える 1

13

shapelessは、厳密な型の不等式に使用されるのと同じ暗黙のあいまいさのトリックを使用して、型演算子(のサブタイプではないことA <:!< Bを意味します)を定義します。AB

trait <:!<[A, B]

implicit def nsub[A, B] : A <:!< B = new <:!<[A, B] {}
implicit def nsubAmbig1[A, B >: A] : A <:!< B = sys.error("Unexpected call")
implicit def nsubAmbig2[A, B >: A] : A <:!< B = sys.error("Unexpected call")

サンプルREPLセッション、

scala> import shapeless.TypeOperators._
import shapeless.TypeOperators._

scala> implicitly[Int <:!< String]
res0: shapeless.TypeOperators.<:!<[Int,String] =
  shapeless.TypeOperators$$anon$2@200fde5c

scala> implicitly[Int <:!< Int]
<console>:11: error: ambiguous implicit values:
 both method nsubAmbig1 in object TypeOperators of type
   [A, B >: A]=> shapeless.TypeOperators.<:!<[A,B]
 and method nsubAmbig2 in object TypeOperators of type
   [A, B >: A]=> shapeless.TypeOperators.<:!<[A,B]
 match expected type shapeless.TypeOperators.<:!<[Int,Int]
              implicitly[Int <:!< Int]
                        ^

scala> class Foo ; class Bar extends Foo
defined class Foo
defined class Bar

scala> implicitly[Foo <:!< Bar]
res2: shapeless.TypeOperators.<:!<[Foo,Bar] =
  shapeless.TypeOperators$$anon$2@871f548

scala> implicitly[Bar <:!< Foo]
<console>:13: error: ambiguous implicit values:
 both method nsubAmbig1 in object TypeOperators of type
   [A, B >: A]=> shapeless.TypeOperators.<:!<[A,B]
 and method nsubAmbig2 in object TypeOperators of type
   [A, B >: A]=> shapeless.TypeOperators.<:!<[A,B]
 match expected type shapeless.TypeOperators.<:!<[Bar,Foo]
              implicitly[Bar <:!< Foo]
                        ^
于 2012-08-27T09:33:33.663 に答える