为什么 shapeless.Nat 没有在运行时访问其值的方法?
Why doesn't shapeless.Nat have a method to access its value at runtime?
这是一个示例程序,它要求 shapeless.Nat
能够在运行时产生它的值,即使它的值在 comile 时间是未知的:
case class Command[N <: Nat](name: String, args: Sized[List[String], N])
case class InvokeCommand[N <: Nat, A](ref: Command[N], args: Sized[List[A], N])
object Program {
val commands: List[Command[Nat]] = List(
Command("foo", Sized("t", "r", "f")),
Command("bar", Sized("h", "i")))
def callCommand[A](name: String, args: List[A]): Option[InvokeCommand] = {
val command = commands.find(_.name ≟ name)
args.sized(command.args.size).map(InvokeCommand(command, _))
}
}
与根本不使用 shapeless.Nat
相比,这仍然会生成一个具有更多静态类型保证的程序。该程序假设 Sized
有一个 size
方法,其中 returns 有一个 shapeless.Nat
方法,但事实并非如此,但实现起来相当简单。
所以我的问题是为什么 shapeless.Nat
没有允许新版本的 sized
方法编译的 toInt
方法(也很容易实现)并在这种情况下工作,其中 N
的运行时值在编译时未知?
我错过了什么或者我应该为 Shapeless 开一个 PR 吗?
目的是 Nat
类型的使用主要是虚幻的,并通过类型推断和隐式解析影响类型检查和计算。在这种情况下,不需要任何运行时表示,并且将浪费所需的额外存储空间。在需要运行时表示的地方,ToInt
类型 class 可以提供它,尽管显然比内在的 toInt
方法更具仪式感。
总而言之,这就是 "by design":本来可以做不同的事情,但它们是预期的。
这是一个示例程序,它要求 shapeless.Nat
能够在运行时产生它的值,即使它的值在 comile 时间是未知的:
case class Command[N <: Nat](name: String, args: Sized[List[String], N])
case class InvokeCommand[N <: Nat, A](ref: Command[N], args: Sized[List[A], N])
object Program {
val commands: List[Command[Nat]] = List(
Command("foo", Sized("t", "r", "f")),
Command("bar", Sized("h", "i")))
def callCommand[A](name: String, args: List[A]): Option[InvokeCommand] = {
val command = commands.find(_.name ≟ name)
args.sized(command.args.size).map(InvokeCommand(command, _))
}
}
与根本不使用 shapeless.Nat
相比,这仍然会生成一个具有更多静态类型保证的程序。该程序假设 Sized
有一个 size
方法,其中 returns 有一个 shapeless.Nat
方法,但事实并非如此,但实现起来相当简单。
所以我的问题是为什么 shapeless.Nat
没有允许新版本的 sized
方法编译的 toInt
方法(也很容易实现)并在这种情况下工作,其中 N
的运行时值在编译时未知?
我错过了什么或者我应该为 Shapeless 开一个 PR 吗?
目的是 Nat
类型的使用主要是虚幻的,并通过类型推断和隐式解析影响类型检查和计算。在这种情况下,不需要任何运行时表示,并且将浪费所需的额外存储空间。在需要运行时表示的地方,ToInt
类型 class 可以提供它,尽管显然比内在的 toInt
方法更具仪式感。
总而言之,这就是 "by design":本来可以做不同的事情,但它们是预期的。