scala - 在 Scala 中保持推导的更高类型

标签 scala

我有一个高阶类型,并致力于用它构建一些 DSL。我正在寻找一种方法来定义可以接受类型而无需显式指定此类型的函数。

self 描述示例:

class Wrap[T] (val data : T)

class DSL {
  def doSomething[T](x : Wrap[T]) =
    println(x.data)
  def <<=[T,W <: Wrap[T]](arg : W) : W = {
    doSomething(arg)
    arg
  }
  def <<-[T](arg : Wrap[T]) : Wrap[T] = {
    doSomething(arg)
    arg
  }
  def <<+[W <: Wrap[_]](arg : W) = {
    doSomething(arg)
    arg
  }
  def <<~(arg : Wrap[_]) = {
    doSomething(arg)
    arg
  }
}

class ExtendedInt(x : Int) extends Wrap[Int](x) {
  def expose() = println(data)
}

object Test {
  val dsl = new DSL
  val exi = new ExtendedInt(3)

  val x1 = dsl <<= exi
  val x2 = dsl <<- exi
  val x3 = dsl <<+ exi
  val x4 = dsl <<~ exi

  x1.expose()
  x2.expose()
  x3.expose()
  x4.expose()
}

我尝试了 4 种不同的方法并得到了 4 种不同的错误:

Casting.scala:15: error: no type parameters for method doSomething: (x: Wrap[T])Unit exist so that it can be applied to arguments (W)
 --- because ---
argument expression's type is not compatible with formal parameter type;
 found   : W
 required: Wrap[?T]

    doSomething(arg)
    ^
Casting.scala:32: error: inferred type arguments [Nothing,ExtendedInt] do not conform to method <<='s type parameter bounds [T,W <: Wrap[T]]
  val x1 = dsl <<= exi
               ^
Casting.scala:38: error: value expose is not a member of Wrap[Int]
  x2.expose()
     ^
Casting.scala:40: error: value expose is not a member of Wrap[_$2]
  x4.expose()
     ^
four errors found

所有错误都非常具有描述性。我不反对 scala 笨拙的类型系统和限制。但我离我的目标还很远,我对寻找其他 hack 来实现所需功能持肯定态度。

还有其他我忽略的方法吗?

最佳答案

看我的回答here (和此处链接的 this other answer)讨论导致您在此处出现问题的类型推断限制。您最好的选择可能是 View 绑定(bind)方法:

class Wrap[T](val data: T)

class DSL {
  def doSomething[T](x : Wrap[T]) { println(x.data) }

  def <<=[T, W <% Wrap[T]](arg : W): W = {
    doSomething(arg)
    arg
  }
}

请注意您的 <:已被 <% 取代.这将按预期工作。

关于scala - 在 Scala 中保持推导的更高类型,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13535068/

相关文章:

regex - Scala 分割字符串正则表达式模式

scala - 如何将 double 组的数据帧转换为向量?

Scala:指定默认泛型类型而不是 Nothing

scala - 如何在 Slick 中进行聚合查询?

scala - 如何在spark数据框中 "negative select"列

c# - 为什么 c# 需要 "var"标识符?

java - java Guava 和 Scala 不可变列表串联的区别

scala - 将 BigDecimal 与整数相乘

scala - 多个 Futures in Play 和使用案例类来保存 future 数据

scala - 在 Scala 列表中使用 'nested' 类型