Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/scala/18.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
为什么scala';s隐式查找忽略嵌套类的伴随对象_Scala_Nested_Implicit_Companion Object_Path Dependent Type - Fatal编程技术网

为什么scala';s隐式查找忽略嵌套类的伴随对象

为什么scala';s隐式查找忽略嵌套类的伴随对象,scala,nested,implicit,companion-object,path-dependent-type,Scala,Nested,Implicit,Companion Object,Path Dependent Type,我在玩下面的代码: class A class B class C trait Codecs[L] { case class Codec[R](val code: L => R, val decode: R => L) object Codec def code[R](foo: L)(implicit codec: Codec[R]): R = codec.code(foo) def decode[R](bar: R)(implicit codec

我在玩下面的代码:

class A
class B
class C

trait Codecs[L] {
    case class Codec[R](val code: L => R, val decode: R => L)
    object Codec

    def code[R](foo: L)(implicit codec: Codec[R]): R = codec.code(foo)
    def decode[R](bar: R)(implicit codec: Codec[R]): L = codec.decode(bar)
}

object Codecs {
    implicit object ACodecs extends Codecs[A] {
        object Codec {
            implicit val ab: Codec[B] = new Codec(_ => new B, _ => new A)
            implicit val ac: Codec[C] = new Codec(_ => new C, _ => new A)
        }
    }
}

object test extends App {
    val codecs = implicitly[Codecs[A]]
    codecs.code[B](new A)
} 
它不会编译,因为编译器无法找到类型为
Codecs.Codec[B]
的隐式值。 据我所知,两个值
ab
ac
的类型是
Acodecs.Codec[\u]
(或类似的类型),这并不是编译器想要的。我还知道,将case类
Codec[\u]
及其同伴移动到trait之外可以解决问题(在使其接受2个类型参数之后)。如果需要隐式值,编译器应该在隐式作用域中包含所需类型的伴随对象。我的问题是:

  • 如何将编译器指向与路径相关的子类型,更具体地说:
  • 是否可以更改
    trait
    的两个方法的签名(理想情况下更改隐式参数的类型签名)以使此编译?如何从trait
    Codecs[\u]
    内部引用类型
    Acodecs.Codec[\u]
  • 比如,如何在嵌套类型上执行typeclass操作

  • 有没有一种模式或什么东西来处理这类问题


  • 问题是您的类型绑定到特定实例,因为它是一个内部类。编译器不知道
    隐式[Codecs[A]
    给出的实例与下一行隐式找到的实例完全相同。例如,如果显式传递它:

    codecs.code[B](new A)(Codecs.ACodecs.Codec.ab)
    
    您将收到以下错误消息:

    type mismatch;
     found   : Codecs.ACodecs.Codec[B]
     required: codecs.Codec[B]
    
    因此,它认为封闭实例可能不同,类型也不同

    我从来没有真正见过这种特定类型的隐式嵌套,即隐式类型类,其中包含路径依赖的隐式类型类。所以我怀疑是否有一种模式来处理它,事实上,我会建议反对它。这似乎太复杂了。以下是我个人如何处理这个案件:

    case class Codec[L, R](val code: L => R, val decode: R => L)
    
    trait Codecs[L] {
      type LocalCodec[R] = Codec[L, R]
    
      def code[R](foo: L)(implicit codec: LocalCodec[R]): R = codec.code(foo)
      def decode[R](bar: R)(implicit codec: LocalCodec[R]): L = codec.decode(bar)
    }
    
    object Codecs {
      implicit object ACodecs extends Codecs[A] {
        implicit val ab: LocalCodec[B] = new LocalCodec(_ => new B, _ => new A)
        implicit val ac: LocalCodec[C] = new LocalCodec(_ => new C, _ => new A)
      }
    }
    
    object test extends App {
      import Codecs.ACodecs._
      val codecs = implicitly[Codecs[A]]    
      codecs.code[B](new A)
    }
    

    您仍然可以使用“半窄化”类型,但它只是一个类型别名,因此没有路径依赖性问题。

    谢谢您的回答。导致我产生这段代码的原因是我想避免调用站点导入。实际上,嵌套类没有(不会)同伴,我没有类型类嵌套。