【问题标题】:Type constraint for type inequality in scala [duplicate]scala中类型不等式的类型约束[重复]
【发布时间】:2012-08-21 13:06:42
【问题描述】:

可能重复:
Enforce type difference

由于在 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 <: BA >: B,还会是A =!= B 的情况吗?如果不是,是否可以修改解决方案,使A =!= B 不是A <: BA >: B 的情况?

【问题讨论】:

  • SO 开发人员应该真正地​​ 修复他们损坏的搜索,以便查找=!= 实际上会列出该问题。这个错误已经知道 4 年了。

标签: scala type-systems


【解决方案1】:

shapeless 定义类型运算符 A <:!< B(意思是 A 不是 B 的子类型)使用与严格类型不等式相同的隐含歧义技巧,

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]
                        ^

【讨论】:

  • 有没有办法让它与更高种类的类型一起工作?类似 A[+T] 类型的东西隐含[A[T]<:>
  • 抱歉,看来我的问题不在于更高种类的类型,但是当您混合 trait {type A[+T] = Iterable[T]} 时,它会设法编译
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-01-17
  • 2017-01-08
  • 1970-01-01
  • 1970-01-01
  • 2017-11-03
相关资源
最近更新 更多