Scala generic class supporting function of multiple arities

前端 未结 1 1532
萌比男神i
萌比男神i 2021-01-13 14:36

Suppose I have the following class Foo, that supports a function of any arity using the tupling trick:

abstract class Foo[T, R] {
  def pull: T => R
}
         


        
1条回答
  •  说谎
    说谎 (楼主)
    2021-01-13 15:27

    If you can be satisfied with defining the implementation as a function rather than a method, then this works:

    abstract class Foo[T, R] {
       type Fn = T => R
       val pull: Fn
    }
    
    class Moo extends Foo[(Int, Int), Int] {
       // The type has to be explicit here, or you get an error about
       // an incompatible type. Using a type alias saves typing out
       // the whole type again; i.e. ((Int, Int)) => Int
       lazy val pull: Fn = (x: Int, y: Int) => x + y
    }
    

    Otherwise, I think you'll need more machinery to support implementation method signatures for different arities:

    trait Foo[T, R] { 
       type Fn = T => R
       val pull: T => R
    } 
    
    trait FooImpl2[T1, T2, R] extends Foo[(T1, T2), R] {
       lazy val pull: Fn = (pullImpl _).tupled
       protected def pullImpl(x: T1, y: T2): R
    }
    
    // similarly for FooImpl3, FooImpl4, ...
    
    class Moo extends FooImpl2[Int, Int, Int] {
       protected def pullImpl(x: Int, y: Int) = x + y
    }
    

    0 讨论(0)
提交回复
热议问题