首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >我如何在Scala中绕过这个重载解析的限制?

我如何在Scala中绕过这个重载解析的限制?
EN

Stack Overflow用户
提问于 2010-10-04 01:39:19
回答 1查看 418关注 0票数 4

在Scala中,重载和隐式参数解析的交互似乎使得以下代码无法使用。

代码语言:javascript
复制
trait Bijection[A, B] extends Function1[A, B] with Unapply[A, B] { self =>
  def apply(a: A): B
  def unapply(b: B): A
}

sealed trait Unapply[A, B] {
  def unapply(b: B): A
}

object Bijection {
  implicit def biject[A](a: A): Biject[A] = new Biject(a)

  implicit object IntStringBijection extends Bijection[Int, String] {
    override def apply(a: Int): String = a.toString
    override def unapply(b: String): Int = b.toInt
  }
}

sealed class Biject[A](a: A) {
  def as[B](implicit f: Function1[A, B]): B = f(a)
  def as[B](implicit f: Unapply[B, A]): B = f unapply a
}

这里的目标是让a.asB执行类型安全转换,而不管隐式作用域中是否有BijectionA,B或BijectionB,A。

这不起作用的原因是隐式解析似乎是在编译器中的重载消除歧义之后发生的,而且由于'as‘的两个实现具有相同的结果类型,编译器甚至不会尝试找出合适的隐式是否在可以执行转换的作用域中。简而言之,隐式解析不用于重载消歧。

我希望重载' as‘的原因是为了避免这个库的用户需要在调用点对bijection的“方向”进行编码;显然,可以这样实现Biject:

代码语言:javascript
复制
sealed class Biject[A](a: A) {
  def viaForward[B](implicit f: Function1[A, B]): B = f(a)
  def viaReverse[B](implicit f: Unapply[B, A]): B = f unapply a
}

但这真的没有吸引力,因为它本质上使皮条客变得多余;人们还可以显式地传递双射,但这样当然就失去了让使用的双射根据作用域而变化的能力。

这个问题有什么好的解决方案吗?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2010-10-04 02:09:49

这个怎么样?

代码语言:javascript
复制
trait Bijection[A, B] extends Function1[A, B] with Unapply[A, B] {
  self =>
  def apply(a: A): B

  def unapply(b: B): A
}

sealed trait Unapply[A, B] {
  def unapply(b: B): A
}

object Bijection {
  implicit def biject[A](a: A): Biject[A] = new Biject(a)

  implicit object IntStringBijection extends Bijection[Int, String] {
    override def apply(a: Int): String = a.toString

    override def unapply(b: String): Int = b.toInt
  }
}

sealed class Biject[A](a: A) {
  def as[B](implicit f: Either[Bijection[A, B], Bijection[B, A]]): B = f.fold(_ apply a, _ unapply a)
}

trait EitherLow {
  implicit def left[A, B](implicit a: A): Either[A, B] = Left(a)
}

object Either extends EitherLow {
  implicit def right[A, B](implicit b: B): Either[A, B] = Right(b)
}

import Bijection._
import Either._

1.as[String]
"1".as[Int]
票数 5
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/3850824

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档