gpt4 book ai didi

scala - 在 Scala 中是否可以动态传递泛型?

转载 作者:行者123 更新时间:2023-12-01 13:19:12 25 4
gpt4 key购买 nike

为了编写 DSL,我想对算术运算建模。

IntDouble 上的乘法运算显然应该在 Int 上导致 Double和一个 Int 它应该导致一个 Int 等等。

在 Scala 中有什么方法可以决定一个类型并动态传递它吗?在下面的代码中,我添加了函数调用 arithmeticReturnType(TL,TR) 的演示方法,然后应将其替换为在 Scala 中实际可用的代码。

trait NumericCol[Repr]

case class Divide[R](l: NumericCol[_], r: NumericCol[_]) extends NumericCol[R]

def divide[TL,TR](left: NumericCol[TL], right: NumericCol[TR]) = Divide[**arithmeticReturnType(TL,TR)**](left, right)

最佳答案

如果您研究过 Scala 集合是如何实现的,您可能已经注意到所有“CanBuildFrom”——用于确定集合操作的最具体返回类型的东西。您可以应用相同的技巧来确保 DSL 中的类型安全:

trait CanDivideInto[A, B, C] {
def divide(a: A, b: B): C
}

implicit object DoubleIntCanDivideIntoDouble
extends CanDivideInto[Double, Int, Double] {
def divide(a: Double, b: Int): Double = a / b
}

implicit object InIntCanDivideIntoInt
extends CanDivideInto[Int, Int, Int] {
def divide(a: Int, b: Int): Int = a / b
}

trait NumericCol[Repr]

case class Divide[A, B, C](
l: NumericCol[A],
r: NumericCol[B],
divider: CanDivideInto[A, B, C]
) extends NumericCol[C]

def divide[A, B, C](
left: NumericCol[A],
right: NumericCol[B]
)(implicit div: CanDivideInto[A, B, C]): NumericCol[C] =
Divide[A, B, C](left, right, div)

val a = new NumericCol[Double]{}
val b = new NumericCol[Int]{}

val c: NumericCol[Double] = divide(a, b)
// val nope: NumericCol[Int] = divide(a, b) // won't compile, good.

Int/DoubleDouble/IntInt/Int 等不同的情况可能会导致一些样板,但我不看不到任何解决方法,因为将整数除以 double 或整数除以 float 或整数除以整数应该最终会导致不同的汇编指令...

关于scala - 在 Scala 中是否可以动态传递泛型?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51405476/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com