scala - 尝试在使用细化时保持类型未包装
问题描述
我正在尝试使用细化来创建基于原语的智能构造函数并避免包装,因为相同的类型可能用于大型集合。我这样做对吗?似乎工作,但有点样板
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]
注意:
- 您不需要单独提及谓词类型
- 它适用于无形标签和精致的自己的新类型。你得到的味道是基于结构的
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 与本机文字类型一起使用)
推荐阅读
- python - 将变量定义为数据库游标python
- javascript - 无法将数据作为道具传递并在反应js的UI中呈现
- php - 为什么使用 PHP 的条带很苗条
- r - R 读取 csv 错误。从另一个值传递文件名
- python - 如何解决 - ValueError: could not convert string to float: ''
- python - 如何将函数参数的字符串值一起存储到单个变量中?
- python - 我如何计算“DataFrame”中大于或小于特定值的值的长度?
- interactive-brokers - InteractiveBrokers API:一种工具的市场状态?
- c# - SocketExceptions 接收端 EventHub
- reactjs - 无法在反应中使用 svg 图像