在构造函数的另一个参数类型中引用路径相关的参数类型
Referencing path-dependent type of an argument in the type of another argument to a constructor
我有自动机,它有依赖类型(我会称它们为关联),用于它们的状态和转换标签。
trait Automaton {
type State
type Label
type Transition = (State, Label, State)
}
现在我想写一个 class,它将一个自动机和一个函数作为其参数,该函数对该特定自动机的转换进行某种计数。我会写:
class AutomataMagic(val aut: Automaton, val h: aut.Transition => Int) {
...
}
然而,that doesn't compile。有什么方法可以指定我希望我的函数专门针对 this 自动机的转换类型执行操作?
我是个白痴。显然,你可以这样做:
class AutomataMagic[A <: Automaton](val aut: Automaton, val h: A#Transition => Int) {}
错误消息说明了一切:
illegal dependent method type: parameter may only be referenced in a subsequent parameter section
作为 Luis Miguel Mejía Suárez ,您需要将 h
移动到另一个参数组。
class AutomataMagic(val aut: Automaton)(val h: aut.Transition => Int) {}
奇怪的是,doesn't work (probably because of this bug).
一个(非常天真的)解决方法是 this。不是很满意,但似乎有用。
class AutomataMagic private(_h: Automaton#Transition => Int, val aut: Automaton) {
val h: aut.Transition => Int = _h.asInstanceOf[aut.Transition => Int]
def this(aut: Automaton)(h: aut.Transition => Int) =
this(h.asInstanceOf[Automaton#Transition => Int], aut)
}
编辑:Luis Miguel Mejía Suárez 建议将特性与伴随对象一起使用。 Here's 我对此的解释:
trait AutomataMagic[A <: Automaton] {
val aut: A
val h: aut.Transition => Int
}
object AutomataMagic {
def apply[A <: Automaton](_aut: A)(_h: _aut.Transition => Int) = new AutomataMagic[A] {
val aut: _aut.type = _aut
val h = _h
}
}
顺便说一下,第一个片段 compiles in Scala 3。
另外,你真的不应该使用这个:
class AutomataMagic[A <: Automaton](val aut: Automaton, val h: A#Transition => Int) {}
不仅 A#Transition
与 aut.Transition
无关(至少使其成为 aut: A
),类型投影 are unsound 将在 Scala 3 中被删除。也许它赢了在这种特定情况下对您来说无关紧要,因为 Transition
是不变的,但它并不安全。
我有自动机,它有依赖类型(我会称它们为关联),用于它们的状态和转换标签。
trait Automaton {
type State
type Label
type Transition = (State, Label, State)
}
现在我想写一个 class,它将一个自动机和一个函数作为其参数,该函数对该特定自动机的转换进行某种计数。我会写:
class AutomataMagic(val aut: Automaton, val h: aut.Transition => Int) {
...
}
然而,that doesn't compile。有什么方法可以指定我希望我的函数专门针对 this 自动机的转换类型执行操作?
我是个白痴。显然,你可以这样做:
class AutomataMagic[A <: Automaton](val aut: Automaton, val h: A#Transition => Int) {}
错误消息说明了一切:
illegal dependent method type: parameter may only be referenced in a subsequent parameter section
作为 Luis Miguel Mejía Suárez h
移动到另一个参数组。
class AutomataMagic(val aut: Automaton)(val h: aut.Transition => Int) {}
奇怪的是,doesn't work (probably because of this bug).
一个(非常天真的)解决方法是 this。不是很满意,但似乎有用。
class AutomataMagic private(_h: Automaton#Transition => Int, val aut: Automaton) {
val h: aut.Transition => Int = _h.asInstanceOf[aut.Transition => Int]
def this(aut: Automaton)(h: aut.Transition => Int) =
this(h.asInstanceOf[Automaton#Transition => Int], aut)
}
编辑:Luis Miguel Mejía Suárez 建议将特性与伴随对象一起使用。 Here's 我对此的解释:
trait AutomataMagic[A <: Automaton] {
val aut: A
val h: aut.Transition => Int
}
object AutomataMagic {
def apply[A <: Automaton](_aut: A)(_h: _aut.Transition => Int) = new AutomataMagic[A] {
val aut: _aut.type = _aut
val h = _h
}
}
顺便说一下,第一个片段 compiles in Scala 3。
另外,你真的不应该使用这个:
class AutomataMagic[A <: Automaton](val aut: Automaton, val h: A#Transition => Int) {}
不仅 A#Transition
与 aut.Transition
无关(至少使其成为 aut: A
),类型投影 are unsound 将在 Scala 3 中被删除。也许它赢了在这种特定情况下对您来说无关紧要,因为 Transition
是不变的,但它并不安全。