Scala-在类型级别减去两个自然数
我们可以在Scala中对自然数的加法和乘法进行编码。但是,可以在类型级别减去两个自然数吗? 我在Scala中复制了一半自然数的以下编码:Scala-在类型级别减去两个自然数,scala,types,type-level-computation,Scala,Types,Type Level Computation,我们可以在Scala中对自然数的加法和乘法进行编码。但是,可以在类型级别减去两个自然数吗? 我在Scala中复制了一半自然数的以下编码: sealed trait Natural { type Plus[That <: Natural] <: Natural } case object Zero extends Natural { override type Plus[That <: Natural] = That } case class Suc[Prev &l
sealed trait Natural {
type Plus[That <: Natural] <: Natural
}
case object Zero extends Natural {
override type Plus[That <: Natural] = That
}
case class Suc[Prev <: Natural](n: Prev) extends Natural {
override type Plus[That <: Natural] = Suc[Prev#Plus[That]]
}
在过去的几个小时里,我一直在尝试实现减法。
使用以下方法,如果您减去的(a-b
)是奇数,我似乎能够正确地减去两个数字:
sealed trait Natural {
type Previous <: Natural
type Minus[That <: Natural] <: Natural
}
case object Zero extends Natural {
override type Previous = Zero.type
override type Minus[That <: Natural] = That
}
case class Suc[Prev <: Natural](n: Prev) extends Natural {
override type Previous = Prev
override type Minus[That <: Natural] = (That#Previous)#Minus[Prev]
}
要了解原因,请在纸上试用m=Suc[Zero.type](Nat1)
,对于奇数/正确的情况,以及m=Suc[Suc[Zero.type]](Nat2)
,对于错误的情况。在这两种情况下,数字n
(如n-m
不重要)
无论如何,我有一种感觉,我可能在正确的轨道上与这种方法,但我被卡住了
n-m
中m>n
时会发生什么
用于尝试repl上的示例:
type Nat0 = Zero.type
type Nat1 = Suc[Nat0]
type Nat2 = Suc[Nat1]
type Nat3 = Suc[Nat2]
type Nat4 = Suc[Nat3]
type Nat5 = Suc[Nat4]
type Nat6 = Suc[Nat5]
type Nat7 = Suc[Nat6]
type Nat8 = Suc[Nat7]
type Nat9 = Suc[Nat8]
type Nat10 = Suc[Nat9]
type Nat11 = Suc[Nat10]
由于减法的递归定义与第二个参数匹配,因此可以定义:
sealed trait Natural {
type ThisType <: Natural
type Previous <: Natural
type Minus[That <: Natural] = That#SubtractThis[ThisType]
type SubtractThis[That <: Natural] <: Natural
}
case object Zero extends Natural {
type ThisType = Zero.type
type Previous = Zero.type
type SubtractThis[That <: Natural] = That
}
case class Suc[Prev <: Natural](n: Prev) extends Natural {
type ThisType = Suc[Prev]
type Previous = Prev
type SubtractThis[That <: Natural] = Previous#SubtractThis[That#Previous]
}
sealed-trait-Natural{
请注意,无论N
和M
如何,结果N#减去这个[M]
将始终是零。请键入。这是因为直接使用N-M=(N-1)-(M-1)
M
的“递归分量”将达到0。键入
,然后保持此状态以进行进一步的递归步骤。同时,N
的“递归分量”将继续递减,直到它也达到0.type
(建议:在纸上尝试N=Suc[Suc[Zero.type]]
和m=Suc[Zero.type]
“请注意,无论N和m是什么,结果N#减去这个[m]将始终是零.type”。不,它不会。例如N=Nat0
和m=Nat1
(或除Nat0
以外的任何东西)。你错过了N#减去这个[m]
表示M-N
,而不是N-M
?您可以看到它在中的工作原理。抱歉;错过了Natural
中的减号。惊人的解决方案。问题已回答。
implicitly[Nat10#Minus[Nat3] =:= Nat7] // Compiles
implicitly[Nat9#Minus[Nat3] =:= Nat6] // Compiles
implicitly[Nat8#Minus[Nat3] =:= Nat5] // Compiles
implicitly[Nat10#Minus[Nat2] =:= Nat8] // Does not compile, while:
implicitly[Nat10#Minus[Nat2] =:= Nat7] // Compiles
implicitly[Nat5#Minus[Nat2] =:= Nat3] // Does not compile, while:
implicitly[Nat5#Minus[Nat2] =:= Nat2] // Compiles
type Nat0 = Zero.type
type Nat1 = Suc[Nat0]
type Nat2 = Suc[Nat1]
type Nat3 = Suc[Nat2]
type Nat4 = Suc[Nat3]
type Nat5 = Suc[Nat4]
type Nat6 = Suc[Nat5]
type Nat7 = Suc[Nat6]
type Nat8 = Suc[Nat7]
type Nat9 = Suc[Nat8]
type Nat10 = Suc[Nat9]
type Nat11 = Suc[Nat10]
sealed trait Natural {
type ThisType <: Natural
type Previous <: Natural
type Minus[That <: Natural] = That#SubtractThis[ThisType]
type SubtractThis[That <: Natural] <: Natural
}
case object Zero extends Natural {
type ThisType = Zero.type
type Previous = Zero.type
type SubtractThis[That <: Natural] = That
}
case class Suc[Prev <: Natural](n: Prev) extends Natural {
type ThisType = Suc[Prev]
type Previous = Prev
type SubtractThis[That <: Natural] = Previous#SubtractThis[That#Previous]
}