gpt4 book ai didi

scala - 使用类型为编译时检查的任意约束建模

转载 作者:行者123 更新时间:2023-12-01 06:45:48 26 4
gpt4 key购买 nike

考虑到 Scala 的强类型系统,我有一个雄心勃勃的项目,我现在即将放弃,因为有用率的努力似乎太高了。

基本上我有一些图形元素( GE ),它们对应于以给定计算速率执行的声音过程。图元素由形成其输入的其他图元素组成。现在有比较随意的约束关于输入的费率。在源语言 (SuperCollider) 中,速率在运行时被检查,这自然是因为它是一种动态类型语言。我想看看我是否可以在编译时强制执行检查。

一些约束相当简单,可以用“arg1 的速率必须至少与 arg2 的速率一样高”的形式表达。但其他人变得错综复杂,例如

“如果 arg0 的汇率是‘需求’,则 args1 的汇率必须是‘需求’或‘标量’或等于封闭的 GE 的汇率”。

问题是:我应该放弃这个吗?以下是运行时检查的外观:

sealed trait Rate
case object demand extends Rate
case object audio extends Rate
case object control extends Rate
case object scalar extends Rate

trait GE { def rate: Rate }

// an example GE:
case class Duty(rate: Rate, in0: GE, in1: GE) extends GE {
def checkRates(): Unit =
require(in0.rate != demand || (in1.rate != demand &&
in1.rate != scalar && in1.rate != rate))
}

对比一下它如何使用速率的类型参数:
sealed trait Rate
trait audio extends Rate
trait demand extends Rate
trait control extends Rate
trait scalar extends Rate

trait GE[R <: Rate]

object Duty {
trait LowPri {
implicit def con1[R, T]: RateCons[R, audio , T] = new ConImpl[R, audio , T]
implicit def con2[R, T]: RateCons[R, control, T] = new ConImpl[R, control, T]
implicit def con3[R, T]: RateCons[R, scalar , T] = new ConImpl[R, scalar , T]

implicit def con4[R, T]: RateCons[R, demand , demand] =
new ConImpl[R, demand, demand]

implicit def con5[R, T]: RateCons[R, demand , scalar] =
new ConImpl[R, demand, scalar]
}
object RateCons extends LowPri {
implicit def con6[R]: RateCons[R, demand, R] = new ConImpl[R, demand, R]
}
private class ConImpl[ R, S, T ] extends RateCons R, S, T ]
sealed trait RateCons[ R, S, T ]

def ar[S <: Rate, T <: Rate](in0: GE[S], in1: GE[T])(
implicit cons: RateCons[audio, S, T]) = apply[audio, S, T](in0, in1)

def kr[S <: Rate, T <: Rate](in0: GE[S], in1: GE[T])(
implicit cons: RateCons[control, S, T]) = apply[control, S, T](in0, in1)
}
case class Duty[R <: Rate, S <: Rate, T <: Rate](in0: GE[S], in1: GE[T])(
implicit con: Duty.RateCons[R, S, T]) extends GE[R]

测试:
def allowed(a: GE[demand], b: GE[audio], c: GE[control], d: GE[scalar]): Unit = {
Duty.ar(b, c)
Duty.kr(b, c)
Duty.ar(b, a)
Duty.ar(b, d)
Duty.ar(a, b)
Duty.kr(a, c)
}

def forbidden(a: GE[demand], b: GE[audio], c: GE[control], d: GE[scalar]): Unit = {
Duty.kr(a, b)
Duty.ar(a, c)
}

一条值得追求的道路?除了代码膨胀之外,还有三件事反对它:
  • 大概有几十个GE s 需要自定义约束
  • 作曲 GE s 变得越来越困难:代码可能需要传递几十个类型参数
  • 转换可能会变得困难,例如想象一个 List[GE[_<:Rate]].map( ??? ) .我的意思是怎么会 Duty.RateCons翻译成 TDuty.RateCons (其中 TDuty 是不同的 GE )...

  • 我已经在这个项目上投入了相当多的时间,所以我不愿意轻易放弃。所以...说服我我在这里做一些有用的事情,或者告诉我我应该回到动态检查的版本。

    最佳答案

    正如 Jesper Nordenberg 所提到的,要做的是定义一组封闭的类型和对这些类型的相等运算。如果你重新审视这个问题,你如何解决它的例子将是可取的。此外,需要提问者所需的类型级编程的示例。

    阅读更多 herehere .

    关于scala - 使用类型为编译时检查的任意约束建模,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5558060/

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