如何将类型约束到另一个的子集?

Syn*_*sso 2 types scala

我觉得这是一个愚蠢的问题,但是这里...我可以定义一个类型是另一个类型的元素的子集吗?这是一个简化的例子.

scala> class Even(i: Int) {
     | assert(i % 2 == 0)  
     | }
defined class Even

scala> new Even(3)
java.lang.AssertionError: assertion failed
Run Code Online (Sandbox Code Playgroud)

这是运行时检查.我可以定义一个类型,以便在编译时检查它吗?IE,输入参数i可证明总是均匀?

Kev*_*ght 7

像Coq和Agda这样的语言的值依赖类型可以做到这一点,但不是Scala.

根据确切的用例,有一些方法可以在类型系统中编码peano数字,但这可能对您有所帮助.

您可能还想尝试定义两者Even以及Odd一些密封的抽象超类型(OddOrEven可能)和一个从任何给定的Integer返回正确实例的工厂方法.

另一种可能性是定义Even为提取器.