繁体   English   中英

Scala类型系统,通过自有类型的参数约束成员的类型

[英]Scala type system, constrain member's type by parameter of own type

这里不太确定标准术语,所以我会试着描述我想要做的事情。 如果您感到好奇,我实际上尝试编写的应用程序是一个类似于Resque或rq的异步任务队列。

我有一个类型TaskDef[ArgsT <: AnyVal, ResultT <: AnyVal] 如果你很好奇, TaskDef代表“如何执行一个异步任务,它接受参数类型ArgsT和结果类型ResultT ,或者任务背后的代码”。

我正在尝试定义一个类型TaskInst[DefT <: TaskDef] 如果你很好奇, TaskInst代表“一个TaskDef和相关的参数来运行它,或者,一个实际的任务实例被提交到队列”。 TaskInst有两个成员, definition: DefT和我不能在代码中写入的类型的arguments

在英语中,我期望的约束是:“对于给定的DefT ,其中DefT是一些TaskDef[ArgsT, ResultT]TaskInst[DefT]应该包含DefTArgsT ”。 也就是说,任务定义的参数类型应该与给予任务的参数类型相匹配。

如何在Scala类型系统中表达这一点?

或者,我是否错误地为我的域建模并尝试做一些非惯用的事情? 一些替代方法会更加惯用吗?

提前致谢!

编辑:

我认为我的历史自我写作Java可能会在这一点上使用未经检查的演员表。 对于一些未经检查的强制转换,这肯定是可行的,只是省略了TaskInst参数类型与嵌入式TaskDef参数类型之间的约束。 但是,我确实想知道这是否是编译器可以强制执行的,并且希望没有太可怕的语法。

将它们定义为抽象类型:

trait TaskDef {
    type Arguments <: AnyVal
    type Result <: AnyVal
}

然后使用类型投影:

trait TaskInst[DefT <: TaskDef] {
    def definition: DefT
    def arguments: DefT#Arguments
}

现场演示

@rightfold给出的答案的附加内容:

如果您希望始终使用类型参数,则需要将类型参数正确传递给类型构造函数。

对不起,我这样说有点含糊不清,所以让我用我当前的代码作为一个具体的例子。

trait TaskDef[ArgT_, ResT_] {
  type ArgT = ArgT_
  type ResT = ResT_
  val name: String
  def exec(arg: ArgT): String \/ ResT
}

class TaskInst[ArgT, ResT, DefT <: TaskDef[ArgT, ResT]] (
  val id: UUID,
  val defn: DefT,
  val arg: ArgT
)

我当前代码与@ rightfold示例的主要TaskDef在于TaskDef采用类型参数。 然后,当TaskInst的声明引用TaskDef ,它必须为类型构造函数提供适当的类型。

我最初错误地传递了占位符。 也就是说,我正在编写class TaskInst[DefT <: TaskDef[_, _] 事实证明,这并不意味着我的意思。 (我不知道。也许其他人可能倾向于遵循同样的思路。所以,这只是一个警告而不是。)不要这样做,因为那时scalac会将预期解释为生成的占位符(正如您可能想象的那样,没有任何内容匹配),然后您会得到如下所示的模糊错误消息。

[error] /Users/mingp/Code/scala-redis-queue/src/main/scala/io/mingp/srq/core/TaskInst.scala:8: type mismatch;
[error]  found   : TaskInst.this.arg.type (with underlying type _$1)
[error]  required: _$1
[error]   val arg: DefT#ArgT_
[error]       ^
[error] one error found

只是张贴这个,希望未来的读者不会陷入我所做的同一个洞。

编辑:

作为进一步的补充,既然我已经尝试了一天,我的印象是这对于异步任务来说实际上并不是一个好的数据模型。 你最好合并,因为TaskDef的独立实例并不真正有用。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM