Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/scala/17.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Scala-在类型级别减去两个自然数_Scala_Types_Type Level Computation - Fatal编程技术网

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

我们可以在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 <: 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
不重要)

无论如何,我有一种感觉,我可能在正确的轨道上与这种方法,但我被卡住了

  • 你知道怎么做吗?也许你能给我指一个类型级别的减法实现
  • 也许这只能通过编码自然数的负数来实现 p、 我不关心在
    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]  
    }