如何在Scala类型类中将帮助程序类型定义为与路径无关?

让我们拥有一个类型类,该类型类根据类型定义了更多可以使用的类型:

trait Container[T] {
  type Elem

  def get(c: T, i: Int): Elem
  def set(c: String, i: Int, v: Elem): T
}

implicit object StringContainer extends Container[String] {
  type Elem = Char

  def get(c: String, i: Int) = c(i)
  def set(c: String, i: Int, v: Char) = c.patch(i, Seq(v), 1)
}

val ops = implicitly[Container[String]]


ops.set("ABC", 1, ops.get("ABC", 1)) // works

ops.set("ABC", 1, 'X') // type mismatch; found   : Char('X') required: ops.Elem

由于类型取决于路径,因此编译器在尝试使用此类型时会抱怨,因此错误是:

类型不匹配;

找到:Char('X')

必填:ops.Elem

你我知道ops.ElemChar我当前的解决方法是改为Elem用作类型参数:

trait Container[T, Elem] {
  def get(c: T, i: Int): Elem
  def set(c: String, i: Int, v: Elem): T
}

implicit object StringContainer extends Container[String, Char] {
  def get(c: String, i: Int) = c(i)
  def set(c: String, i: Int, v: Char) = c.patch(i, Seq(v), 1)
}

缺点是需要时调用类型类,需要提供所有类型参数:

val ops = implicitly[Container[String, Char]]

是否有某种方法可以在类型类中定义类型,以便可以将它们用作与路径无关的类型?

马里奥·加里奇(Mario Galic)

你只是要求

Container[String]

代替

Container[String] { type Elem = Char }

尝试类型细化

object Container {
  implicit val strContainer: Container[String] { type Elem = Char } = new Container[String] {
    type Elem = Char

    def get(c: String, i: Int) = c(i)
    def set(c: String, i: Int, v: Char) = c.patch(i, Seq(v), 1)
  }
}

val ops = implicitly[Container[String] { type Elem = Char }]
ops.set("ABC", 1, 'X') // ok

带有辅助模式的像

object Container {
  type Aux[T,Elem0] = Container[T] { type Elem = Elem0 }

  implicit val strContainer: Aux[String, Char] = new Container[String] {
    type Elem = Char

    def get(c: String, i: Int) = c(i)
    def set(c: String, i: Int, v: Char) = c.patch(i, Seq(v), 1)
  }
}


val ops = implicitly[Container.Aux[String,Char]]
ops.set("ABC", 1, 'X') // ok

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章

如何在Scala中将依赖于路径的类型与类型类一起使用

如何在Typescript中将类定义指定为参数类型

如何在Flow中将道具类型定义为<div>?

如何在Scala Cats中创建自定义类型构造函数的类型为Monad [F [_]]的类的实例

如何在类中为模板定义类型别名

如何在Scala中将擦除类型缩小(强制转换)为交叉类型?

如何在golang类型结构中将列类型定义为长文本?

如何在Scala中为泛型类型提供默认类型类?

如何使用 ts 在 vue3 中将 ref 数据定义为类类型

如何在Scala案例类中将“ [T]的子代”指定为类型

如何在Scala的类型类中使用依赖类型?

如何在Scala中将类型为Map [String,Map [String,Any]]的嵌套映射转换为JSON?

如何在C ++中为不同的模板类型使用不同的类定义?(类超载?)

如何在自定义帖子类型循环中将帖子标签添加为类?

如何在Postgres C函数中将数组返回为具有自定义类型的数组?

如何创建用于检查值是否为给定类实例的自定义类型保护程序?

如何在Scala中为Traversable的任何子类创建类型类实例

如何在C ++中为同一类定义不同的类型

如何在YAML Swagger定义中将属性类型定义为字符串列表(列表,集合,数组,集合)

如何在YARD中将当前类引用为返回类型?

如何在TypeScript中将函数返回的类用作类型?

如何在变量声明中将Type类用作类型

Scala泛型:如何声明类型必须为case类?

如何在Typescript中将通用类型键入为接口的子集?

如何在 TypeScript 中将泛型类型提示为参数?

如何在kotlin中将函数的返回类型设置为mutableListOf

如何检查类型是否为自定义类

如何在Typescript中将组件类定义为接口字段?

在Dart中将类型定义为“可比较”