2015-11-20 61 views
0

我已经张贴在斯卡拉用户论坛这个问题的仿制药,落实特质和方法

https://groups.google.com/forum/#!topic/scala-user/xlr7KmlWdWI

和我收到这我很高兴回答。然而,同时我想确定这是否是唯一的结论。由于

我的问题是,比方说,我有,

trait Combinable[A] { 
    def join[B](l: List[A]): B 
} 

当我实现这个特征与A作为字符串和B诠释,例如,

class CombineString extends Combinable[String] { 
    override def join[Int](strings: List[String]) = string.size 
} 

显然,诠释 ,加入方法旁边,不是Scala整数类,编译该代码将会失败。或者,我可以重写我的特点为

trait Combinable[A, B] { 
    def join(l: List[A]): B 
} 

trait Combinable[A] { 
    def join[B](l: List[A])(f: List[A] => B): B 
} 

我的问题是,我怎么能实现如在第一个例子定义,因为它是特质?如果第一个例子因为定义的方式而没有实际用途,为什么编译器不会投诉?再次感谢。

+0

编译器不会抱怨,因为它不知道A和B通过了什么。开发人员必须保持纪律。 –

+0

我明白,但从人的角度来看(我和其他人的回答)只有一个结果,抛出异常,编译器引发警告是很好的。除非有其他结果我不知道 – thlim

+0

在今天的编译器中没有这样的术语\实体作为“实际使用” – Odomontois

回答

2

您不能期望编译器能够理解哪种类型的组合对您有意义,但是您可以将这种意义指定为多参数含义中类型之间的关系。

结果基本上是两种您拒绝的方法的组合,但具有所需的语法。

两个拒绝形式首次成为隐式类型:

trait Combine[A, B] { 
    def apply(l: List[A]): B 
} 

接下来,您可以定义合适的类型组合及其意义

implicit object CombineStrings extends Combine[String, String] { 
    def apply(l: List[String]) = l.mkString 
} 

implicit object CombineInts extends Combine[Int, Int] { 
    def apply(l: List[Int]) = l.sum 
} 

implicit object CombinableIntAsString extends Combine[Int, String] { 
    def apply(l: List[Int]) = l.mkString(",") 
} 

最后,我们修改第二否决形式隐藏f参数隐resulution :

trait Combinable[A] { 
    def join[B](l: List[A])(implicit combine: Combine[A, B]): B = combine(l) 
} 

否W使您可以定义

val a = new Combinable[String] {} 
val b = new Combinable[Int] {} 

而且检查

a.join[String](List("a", "b", "c")) 
b.join[Int](List(1, 2, 3)) 
b.join[String](List(1, 2, 3)) 

运行很好,而

a.join[Int](List("a", "b", "c")) 

使编译器哭,直到你能提供StringInt之间的关系实际使用证据以隐含价格的形式

0

我的问题是,我该如何实现第一个示例中定义的特征,因为它是?

class CombineString extends Combinable[String] { 
    override def join[B](strings: List[String]) = null.asInstanceOf[B] 
    // or, for that matter, anything and then .asInstanceOf[B] 
} 

编译器怎么会知道这是不是你想要的?