【问题标题】:Issue with Scala Implicit ConversionsScala 隐式转换的问题
【发布时间】:2019-04-01 22:00:15
【问题描述】:

在下面的代码摘录中,最后一条语句没有编译。但是,紧接在该语句之前的语句实际上可以编译。这个倒数第二个语句是我希望编译器将最后一个语句转换为的语句。我不明白为什么它不起作用。任何帮助表示赞赏。

trait ParameterizedBy[A, B] {
    val parameterized: B
  }

object ParameterizedBy {
  implicit def toParameterized[A, B, C](p: ParameterizedBy[A, B])(
    implicit f: B => C): C = f(p.parameterized)
}

trait Wraps[A] {
  val wrapped: A
}

object Wraps {
  implicit def toWrapped[A](w: Wraps[A]): A = w.wrapped
}

val p = new ParameterizedBy[String, Wraps[Int]] {
  override val parameterized: Wraps[Int] = new Wraps[Int] {
    override val wrapped = 6
  }
}

ParameterizedBy.toParameterized(p)(Wraps.toWrapped) + 5

p + 5

【问题讨论】:

    标签: scala generics implicit-conversion implicit


    【解决方案1】:

    将方法隐式转换为A => C 是有问题的,因为编译器无法轻松枚举所有可能的类C 具有预期方法+,然后去搜索所有采用B 并给出C 的可能方法——这个搜索将永远持续下去。

    我建议避免 B => C 类型的隐式参数用于未知类型 C。如果你想要一个转换器,那么给它一个特定的名称,例如

    trait Unwrap[A, B] extends (A => B)
    

    然后你只在这个链接的隐式中使用。

    您可能会尝试的粗略草图:

    import scala.language.implicitConversions
    
    trait ParameterizedBy[A, B] {
        val parameterized: B
      }
    
    object ParameterizedBy {
      implicit def toParameterized[A, B, C](p: ParameterizedBy[A, B])(
        implicit f: Unwrap[B, C]): C = f(p.parameterized)
    }
    
    trait Wraps[A] {
      val wrapped: A
    }
    
    object Wraps {
      implicit def toWrapped[A](w: Wraps[A]): A = w.wrapped
    }
    
    trait Unwrap[A, B] extends (A => B)
    
    object Unwrap {
      implicit def unwrap[A]: Unwrap[Wraps[A], A] = new Unwrap[Wraps[A], A] {
        def apply(w: Wraps[A]): A = w.wrapped
      }
    }
    
    val p = new ParameterizedBy[String, Wraps[Int]] {
      override val parameterized: Wraps[Int] = new Wraps[Int] {
        override val wrapped = 6
      }
    }
    
    p - 5         // works
    (p: Int) + 5  // works with type ascription (to avoid conflicts with `+ String`)
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2012-01-02
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-08-30
      • 1970-01-01
      • 2018-09-16
      相关资源
      最近更新 更多