在类型和唯一值之间建立已知的 1:1 关系

发布于 2024-10-20 05:16:54 字数 575 浏览 6 评论 0原文

鉴于我有一种使用密封特征和表示值的 case 对象的枚举,是否可以强制执行一种机制来检索给定类型的单个唯一值,而不需要隐式参数?

对于隐式,是否可以

sealed trait Enum
sealed trait Value1 extends Enum
case object Value1 extends Value1 { implicit val me: Value1 = Value1 }
sealed trait Value2 extends Enum
case object Value2 extends Value2 { implicit val me: Value1 = Value1 }

def test[V <: Enum](implicit evidence: V): V = evidence

test[Value1]

删除隐式参数进行测试?也就是说,确保 V 是 Enum 的定义子类型(显然, test[Enum] 应该失败)。棘手的结是:

object Enum {
  def unique[V <: Enum]: V = ???
}

Given that i have a kind of enumeration using a sealed trait and case objects representing the values, is it possible to enforce a mechanism to retrieve the single unique value for a given type, without requiring an implicit argument?

with implicits this would be

sealed trait Enum
sealed trait Value1 extends Enum
case object Value1 extends Value1 { implicit val me: Value1 = Value1 }
sealed trait Value2 extends Enum
case object Value2 extends Value2 { implicit val me: Value1 = Value1 }

def test[V <: Enum](implicit evidence: V): V = evidence

test[Value1]

is it possible to drop the implicit argument to test? that is, to ensure that V is a defined subtype of Enum (obviously, test[Enum] should fail). the gordian knot is:

object Enum {
  def unique[V <: Enum]: V = ???
}

?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

白况 2024-10-27 05:16:54

看起来好像您正在尝试根据类型查找特定值或行为,并且出于某种原因不想将此行为放入某个公共超类中。

看起来您似乎正在尝试使用隐式对象和伴生对象来通过模拟 Java 静态的一些特征来实现此目的。这是一个你绝对想从你的心理工具箱中删除的模型,从面向对象编程的角度来看,它已经无可救药地被破坏了。

真正想要的是临时多态性,我们有更好的方法来做到这一点。有趣的是,它仍然使用隐式和上下文绑定:

sealed trait Enum
sealed trait Value1 extends Enum
sealed trait Value2 extends Enum

case object Value1 extends Value1
case object Value2 extends Value2

sealed abstract class UniqValue[T] { def value: T }
implicit object Value1HasUniq extends UniqValue[Value1] { val value = Value1 }
implicit object Value2HasUniq extends UniqValue[Value2] { val value = Value2 }

def test[V <: Enum : UniqValue]: V = implicitly[UniqValue[V]].value

您还可以将 test 定义为:

def test[V <: Enum](implicit ev: UniqValue[V]): V = ev.value

它的作用完全相同,手动删除编译器无论如何都会为您执行的上下文绑定的语法糖。

基本上,这一切都有效,因为编译在解析隐式时也会考虑类型参数。

如果您想了解更多有关此类内容的信息,则要搜索的神奇短语是“类型类”

It looks as though you're trying to look up specific values or behaviour based on type and, for whatever reason don't want to put this behaviour in some common superclass.

It also looks as though you're trying to use implicits and companion objects to achieve this by emulating some of the characteristics of Java's statics. This is a model you absolutely want to be dropping from your mental toolkit, it's hopelessly broken from the perspective of object oriented programming.

What you really want is ad-hoc polymorphism, and we have better ways to do that. Interestingly, it does still use implicits, and a context bound:

sealed trait Enum
sealed trait Value1 extends Enum
sealed trait Value2 extends Enum

case object Value1 extends Value1
case object Value2 extends Value2

sealed abstract class UniqValue[T] { def value: T }
implicit object Value1HasUniq extends UniqValue[Value1] { val value = Value1 }
implicit object Value2HasUniq extends UniqValue[Value2] { val value = Value2 }

def test[V <: Enum : UniqValue]: V = implicitly[UniqValue[V]].value

You could also define test as:

def test[V <: Enum](implicit ev: UniqValue[V]): V = ev.value

Which does exactly the same thing, manually removing the syntactic sugar of context bounds that the compiler would do for you anyway.

Basically, it all works because the compile will also consider type params when resolving implicits.

If you want to read up more on this kind of thing, the magic prhrase to search for is "type classes"

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文