繁体   English   中英

scala隐式类方法类型不匹配的reduce与非隐式方法的函数currying

[英]scala implicit class method type mismatch in reduce vs non-implicit method with function currying

问题:

关于隐式类的东西,混淆reduce()。 在隐式类内部时,编译器会在reduce()第二个参数上抱怨。 但是当相同的代码在非隐式方法中时,它编译并正常工作。

我对隐含类缺少什么?

码:

object ImpliCurri {
    implicit class MySeq[Int](val l: Seq[Int]) {
        //not compiling
        final def mapSum(f:Int=>Int):Int = {
            l.map(x=>f(x)).reduce(_+_)
       //compile error on reduce: Type mismatch. Expected String, fount Int
        }
    }

    // works fine
    def mySum(l:Seq[Int], f:Int=>Int):Int = {
        l.map(x=>f(x)).reduce(_+_)
        // compiles and works no issues
    }
}

你需要摆脱类型参数Int Int中所隐含的类的情况下,实际上不是类型Int ,而是它是一个的阴影的名字自由类型参数Int

隐藏编译器错误的原因是编译器从lambda _ + _推断类型Any (因为类型参数可能是任何东西),并假设+将来自类型为AnytoString 如果在类声明中用T替换Int ,您将看到错误是相同的。

这将有效:

implicit class MySeq(val l: Seq[Int]) {
    final def mapSum(f: Int => Int): Int = {
        l.map(x => f(x)).reduce(_ + _)
    }
 }

它实际上与implicits没有任何关系。 如果它只是一个普通的class你会得到同样的错误。

原因是你已经声明了一个泛型类型: MySeq[Int]恰好被称为Int 所以当你说f: Int => Int你会想“哦,那是一个整数”,编译器认为,“哦,这意味着你可以在那里填写任何类型!”。 (将所有的Int替换为A ,它的工作方式相同。)

现在编译器处于绑定状态。 什么+你可以适用于任何类型的? 好吧,你可以将任何东西转换为String+String上定义。 因此,当编译器意识到此方法不起作用时,您会收到一个非常误导性的错误消息。

只需删除[Int] ,你的所有Int实际意味着你认为它们的意思,隐式类版本将正常工作。

MySeq[Int](val l: Seq[Int])替换MySeq[Int](val l: Seq[Int]) MySeq(val l: Seq[Int])

编译器消息的说明:
MySeq[Int]部分为名为Int MySeq类定义一个抽象类型参数,它是(自动) Any的子类并scala.Int实际的scala.Int 然后编译器尝试调用Any实例的+方法。 它看到一个隐式类scala.Predef.any2stringadd的声明,它有一个带有签名def +(other: String): String ,因此编译器认为第二个参数+应该是一个String

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM