在使用精化时试图保持类型展开

Trying to keep types unwrapped when using refined

我正在尝试使用精化来创建基于基元的智能构造函数并避免包装,因为在大型集合中可能会使用相同的类型。我这样做对吗?似乎工作但有点样板

    type ONE_Pred = = MatchesRegex[W....
    type ONE = String @@ ONE_Pred
    type TWO_Pred = OneOf[...
    type TWO = String @@ TWO_PRED 

然后

 case class C(one:ONE, two:TWO)
 object C {
  def apply(one:String, two:String):Either[String, C] = 
  (
   refineT[ONE_Pred](one),
   refineT[TWO_Pred](two)
  ).mapN(C.apply)
}

Refined 有一种机制可以创建类似伴侣的对象,这些对象已经定义了一些实用程序:

type ONE = String @@ MatchesRegex["\d+"]
object ONE extends RefinedTypeOps[ONE, String]

注意:

  1. 您不需要单独提及谓词类型
  2. 它适用于无形标签和精炼自己的新类型。你得到的风味是基于type ONE.
  3. 的结构

你得到:

  • ONE("literal") 替代 refineMT/refineMV
  • ONE.from(string) 替代 refineT/refineV
  • ONE.unapply 所以你可以做到 string match { case ONE(taggedValue) => ... }
  • ONE.unsafeFrom 当你唯一的选择是抛出异常时。

使用这些 "companions",可以编写更简单的代码,而无需提及任何谓词类型:

object C {
  def apply(one: String, two: String): Either[String, C] =
    (ONE.from(one), TWO.from(two)).mapN(C.apply)
}

scastie 中的示例,将 2.13 与本机文字类型一起使用)