定义新类型,其域是 Scala 中另一种类型的子集

问题描述 投票:0回答:1

以偶数为例,我想定义域为偶数的Even类型使用函数

val isEven(i: Int): Boolean = i % 2 == 0

我如何在 Scala 3 中使用不透明关键字来做到这一点...

opaque type Even = ??? // use Int and filter using isEven
或者如果那不起作用,

type Even = ???

基本原理是使用函数作为构建块来创建新类型,而不是通过使用 newtype 作为 scala-even-type-number 或使用 Refined Types

使事情复杂化
scala domain-driven-design scala-3
1个回答
1
投票

类似以下内容:

object Evens:
  opaque type Even = Int

  object Even:
    def apply(i: Int): Even = if i % 2 == 0 then i else sys.error(s"$i is odd")
    def unsafe(i: Int): Even = i
    def safe(i: Int): Option[Even] = Option.when(i % 2 == 0)(i)

  extension (x: Even)
    def toInt: Int = x
    def +(y: Even): Even = x + y
    def *(y: Int):  Even = x * y
    def half: Int = x / 2
end Evens

import Evens.*
// val x: Even = 2 // doesn't compile
val x: Even = Even(2)
// val x: Even = Even(3) // RuntimeException: 3 is odd

https://docs.scala-lang.org/scala3/book/types-opaque-types.html

https://docs.scala-lang.org/scala3/reference/other-new-features/opaques.html

如果您希望

Even(3)
在编译时而不是运行时失败,请将
def apply(i: Int): Even = ...
替换为

import scala.compiletime.{error, erasedValue, constValue, codeOf, summonFrom}
import scala.compiletime.ops.int.%
import scala.compiletime.ops.any.{==, ToString}

inline def apply[I <: Int with Singleton](inline i: I): Even =
  inline erasedValue[I % 2] match
    case _: 0 => i
    case _    => error(codeOf(i) + " is odd")

inline def apply[I <: Int with Singleton](inline i: I): Even =
  inline if constValue[I % 2] == 0 then i else error(codeOf(i) + " is odd")

inline def apply[I <: Int with Singleton](inline i: I): Even = 
  inline erasedValue[I % 2 == 0] match
    case _: true => i
    case _       => error(constValue[ToString[I]] + " is odd")

inline def apply[I <: Int with Singleton](inline i: I): Even = 
  summonFrom {
    case _: (I % 2 =:= 0) => i
    case _                => error(constValue[ToString[I]] + " is odd")
  }

https://docs.scala-lang.org/scala3/reference/metaprogramming/inline.html

https://docs.scala-lang.org/scala3/reference/metaprogramming/compiletime-ops.html

© www.soinside.com 2019 - 2024. All rights reserved.