这是关于编程语言中类型的一个非常基本的问题。现在,我使用相同的类型Integer
进行非常不同的计算:例如,用于计算阶乘和斐波那契数。
但是Integer
对我来说,这些计算似乎是非常广泛的类型。如果我定义其他更具体的类型Factorial
或者Fibonacci[Integer]
相反,该怎么办?
这样的类型有意义吗?我可以用Java或Scala定义它们吗?
我不确定这不是您要查找的内容,但是如果您具有自然数的类型级表示(在此答案中,我将使用Shapeless),则可以编写一个有意义的Fibonacci
类型类,例如:
import shapeless._, Nat._
trait Factorial[N <: Nat] { type Value <: Nat }
implicit object fact0 extends Factorial[_0] { type Value = _0 }
implicit object fact1 extends Factorial[_1] { type Value = _1 }
implicit def factN[N <: Nat, X <: Nat, Y <: Nat, Z <: Nat](implicit
nf: Factorial[N] { type Value = X },
sf: Factorial[Succ[N]] { type Value = Y },
sum: ops.nat.Sum.Aux[X, Y, Z]
) = new Factorial[Succ[Succ[N]]] { type Value = Z }
然后,我可以要求类型系统证明例如第七个斐波那契数为十三(因为是):
scala> implicitly[Factorial[_7] { type Value = _13 }]
res1: Factorial[shapeless.Nat._7]{type Value = shapeless.Nat._13} = $anon$1@795adafd
但不是第七斐波那契数是十二:
scala> implicitly[Factorial[_7] { type Value = _12 }]
<console>:23: error: could not find implicit value for parameter e: Factorial[shapeless.Nat._7]{type Value = shapeless.Nat._12}
implicitly[Factorial[_7] { type Value = _12 }]
^
这种方法使用自然数的教堂编码。您还可以在Scala 2.10中将单例类型与宏一起使用-例如,有关我在Scala中对单例类型的一些讨论,请参见我的博客文章。
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句