首页 > 解决方案 > 尝试在使用细化时保持类型未包装

问题描述

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

    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)
}

标签: scalashapelessrefined

解决方案


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

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

注意:

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

你得到:

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

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

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

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


推荐阅读