【问题标题】:Overriding Method (Int => Int => Int) of TraitTrait 的覆盖方法 (Int => Int => Int)
【发布时间】:2016-04-13 18:12:49
【问题描述】:

鉴于以下特征:

scala> trait Foo { 
     |   def f: Int => Int => Int
     | }
defined trait Foo

我创建了一个试图实例化Foo#f的类:

scala> class FooImpl extends Foo {
     |  override def f(x: Int, y: Int) = 100
     | }
<console>:11: error: class FooImpl needs to be abstract, since method f in trait Foo of type => Int => (Int => Int) is not defined
       class FooImpl extends Foo {
             ^

我能够通过以下方式解决它:

scala> class FooImpl extends Foo {
     |   override def f = x => y => 100
     | }
defined class FooImpl

然后我可以做一个实例:

scala> new FooImpl().f(10)(20)
res3: Int = 100

但是,我将如何创建一个实现 Foo#fdef f(x: Int, y: Int) = 100Foo,即没有柯里化?

最后,我试过了:

scala> trait Bar { def f: (Int, Int) => Int }
defined trait Bar

但这也失败了:

scala> class BarImpl extends Bar { 
     |  override def f(x: Int, y:Int) =100
     | }
<console>:11: error: class BarImpl needs to be abstract, since method f in trait Bar of type => (Int, Int) => Int is not defined
       class BarImpl extends Bar {
             ^

【问题讨论】:

    标签: scala


    【解决方案1】:

    这些类型不兼容。

    def f: Int => Int => Int
    

    .. 是一个无参数方法,它返回一个带有一个参数Int函数,它返回一个带有一个参数Int 的函数,它返回一个Int .

    def f: (Int, Int) => Int
    

    .. 是一个无参数方法,它返回一个带有两个Int 类型参数的函数,它返回Int

    def f(x: Int, y: Int): Int
    

    .. 是一个双参数方法,带有两个Int 参数,返回一个Int

    所有这些都是根本不同的。你不能用任何其他覆盖它们中的任何一个。如果你想要f(x: Int, y: Int): Int,那么这就是首先应该在Foo 中的签名。否则,您必须使用 curry、eta-expand 或其他方法来使签名匹配。

    【讨论】:

      【解决方案2】:

      如果你想让 trait 定义非柯里化版本,那么它需要是这样的:

      trait Foo {
        def f(x: Int, y: Int): Int
      }
      

      这里的(x: Int, y: Int)表示f接受Int这两个参数,: Int表示返回值必须是Int

      【讨论】:

        【解决方案3】:

        这是创建实现Foo trait 的FooImpl 的方法。我们也可以在不使用currying的情况下访问Foo#f。

        trait Foo{
        def f1:Int=> Int=> Int
        def f2: (Int, Int) => Int
        }
        
        class FooImpl extends Foo{
        
            //actual implementors of f1 and f2 in Foo trait
            def g0=g1
            def g1=g2
            def g2=20
            def add(a:Int, b:Int)=a+b
        
            override  def f1=g0=>g1=>g2
            override def f2=add 
        }
        

        现在我们可以实例化FooImpl 类而不用currying。

        var x = new FooImpl
        println(x.f1.apply(1).apply(1))  //results 20
        println(x.f2(10,10))             //results 20
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2021-07-29
          • 2012-06-09
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多