在Scala中,最简单的方法是链接由类型类定义的函数,并且取决于哪个输出类型? [英] In scala, what is the easiest way to chain functions defined with a type class and of which output type depends on it?

查看:42
本文介绍了在Scala中,最简单的方法是链接由类型类定义的函数,并且取决于哪个输出类型?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

假设已定义类 Thing ,并且操作 + 与类型类相关联:

Assuming that a class Thing is defined, and an operation + is associated with a type class:

  trait TypeClass[X, Y] {

    type Out
    def v: Out
  }

  object TypeClass {

    implicit def summon[X <: Int, Y <: Int]: TypeClass[X, Y] = new TypeClass[X, Y] {

      type Out = Int

      override def v: Out = 2
    }
  }

  case class Thing[X]() {

    def +[Y](that: Thing[Y])(implicit typeClass: TypeClass[X, Y]): typeClass.Out = typeClass.v
  }

现在,如果我想定义一个快捷方式函数 + 2x ,它表示 X + Y + Y .我的第一个本能是引入一个隐式参数:

Now if I want to define a shortcut function +2x, which represents X + Y + Y. My first instinct was to introduce an implicit parameter:

    def ++[Y, Z](that: Thing[Y])(implicit t1: TypeClass[X, Y] { type Out <: Z }, t2: TypeClass[Z, Y]): t2.Out = t2.v

但是随后t2变成了无法填补的鞋子:

But then t2 becomes an impossible shoe to fill:


    assert(Thing(1) + Thing(2) == Thing(2)) // works fine

    assert(Thing(1) ++ Thing(2) == Thing(2)) // TypeClass.scala:34: could not find implicit value for parameter t2: TypeClass.this.TypeClass[Z,Int]

我还可以使用更直观的格式:

I could also use a more intuitive format:


    def +++[Y, Z](that: Thing[Y])(implicit t1: TypeClass[X, Y] { type Out <: Y }, a: Any = this + that + that): a.type =
      a

不幸的是,隐式t1无法使定义结果的表达式可见:

unfortunately implicit t1 cannot be made visible to the expression that defines the result:

TypeClass.scala:29: type mismatch;
 found   : a.type (with underlying type Any)
 required: AnyRef

那么定义这个最简单,最直观的方法是什么?

so what is the easiest, most intuitive way to define this?

非常感谢您的意见

推荐答案

您丢失了类型优化功能.替换

You lost type refinement. Replace

implicit def summon[X <: Int, Y <: Int]: TypeClass[X, Y] = new TypeClass[X, Y] {...

使用

implicit def summon[X <: Int, Y <: Int]: TypeClass[X, Y] {type Out = Int} = new TypeClass[X, Y] {...

我想 case class Thing [X]()应该是 case class Thing [X](x:X).然后

assert(Thing(1) + Thing(2) == 2) 
assert(Thing(1) ++ Thing(2) == 2)

工作.

如何调试隐式: 查看全文

登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆