如何使aux类型编译?

时间:2019-04-06 17:44:10

标签: scala types

我有以下aux类型的示例,该示例无法编译:

trait Foo[A] {

  type B

  def value: B

}

object Foo {

  type Aux[A0, B0] = Foo[A0] { type B = B0}
 implicit def footInt = new Foo[Int] {
   override type B = String

   override def value = "Hey!"
 }

  implicit def fooString = new Foo[String] {
    override type B = Boolean

    override def value = true
  }

}


import cats._
import cats.implicits._

object App {

  def main(args: Array[String]): Unit = {

    val x: Id[String] = "Hello"

    println(foo(1))
    println(foo("Hello"))

    println(fooAux(1)(x))

  }

  def foo[T](t: T)(implicit f: Foo[T]): f.B = f.value

  def fooAux[T, R] (t: T) (implicit f: Foo.Aux[T, R], id: Id[R]) : R = f.value

}

编译器抱怨:

Error:(15, 22) not enough arguments for method fooAux: (implicit f: com.sweetsoft.Foo.Aux[Int,R], implicit id: cats.Id[R])R.
Unspecified value parameter id.
    println(fooAux(1)(x))
Error:(21, 55) parameter value id in method fooAux is never used
  def fooAux[T, R] (t: T) (implicit f: Foo.Aux[T, R], id: Id[R]) : R = f.value
Error:(4, 23) Unused import
import cats.implicits._ 

我在做什么错了?

1 个答案:

答案 0 :(得分:1)

它经过少量修改即可编译:

trait Foo[A] {
  type B
  def value: B
}

object Foo {

  type Aux[A0, B0] = Foo[A0] { type B = B0 }

  implicit val footInt = new Foo[Int] {
    override type B = String
    override def value = "Hey!"
  }

  implicit def fooString = new Foo[String] {
    override type B = Boolean
    override def value = true
  }

}

object App {

  type Id[X] = X

  def main(args: Array[String]): Unit = {
    implicit val x: Id[String] = "Hello"
    println(foo(1))
    println(foo("Hello"))
    println(fooAux(1))

  }

  def foo[T](t: T)(implicit f: Foo[T]): f.B = f.value

  def fooAux[T, R] (t: T) (implicit f: Foo.Aux[T, R], id: Id[R]): R = id

}

第一个错误很清楚:fooAux的第二个参数列表需要两个参数,但是您只传递了一个x

第二条错误消息也很普通:您永远不会使用id

只要您提供隐式String(我想您要使x隐含),其余的一切就照原样工作。