2010-04-28 34 views
10

Tôi đang cố định nghĩa một kiểu cấu trúc xác định bất kỳ bộ sưu tập nào có phương thức "thêm" (ví dụ, một bộ sưu tập java). Sử dụng này, tôi muốn xác định một vài chức năng bậc cao hoạt động trên một tập hợp xác địnhSử dụng các kiểu cấu trúc Scala với các kiểu trừu tượng

object GenericTypes { 
    type GenericCollection[T] = { def add(value: T): java.lang.Boolean} 
} 

import GenericTypes._ 
trait HigherOrderFunctions[T, CollectionType[X] <: GenericCollection[X]] { 
    def map[V](fn: (T) => V): CollectionType[V] 
    .... 
} 

class RichJList[T](list: List[T]) extends HigherOrderFunctions[T, java.util.List] 

này không biên dịch với các lỗi sau

error: Parameter type in structural refinement may not refer to abstract type defined outside that same refinement 

tôi đã cố gắng loại bỏ các tham số trên GenericCollection và đặt nó về phương pháp:

object GenericTypes { 
    type GenericCollection = { def add[T](value: T): java.lang.Boolean} 
} 
import GenericTypes._ 
trait HigherOrderFunctions[T, CollectionType[X] <: GenericCollection] 

class RichJList[T](list: List[T]) extends HigherOrderFunctions[T, java.util.List] 

nhưng tôi nhận được một lỗi:

error: type arguments [T,java.util.List] do not conform to trait HigherOrderFunctions's type parameter bounds [T,CollectionType[X] <: org.scala_tools.javautils.j2s.GenericTypes.GenericCollection] 

Bất cứ ai có thể cho tôi một số lời khuyên về cách sử dụng kiểu nhập cấu trúc với các tham số được nhập trừu tượng trong Scala? Hoặc làm thế nào để đạt được những gì tôi đang tìm kiếm để đạt được? Cám ơn rất nhiều!

Trả lời

4

Như bạn có thể thấy trong ticket 1906 bạn không thể sử dụng loại trừu tượng được xác định bên ngoài loại cấu trúc do thiếu thông tin loại khi chạy.

Điều này được nêu trong Scala Language Reference (3.2.7 Compound Types):

Within a method declaration in a structural refinement, the type of 
any value parameter may only refer to type parameters or abstract types that are 
contained inside the refinement. 

Cách thông thường để thêm các phương pháp mới cho một loại là do chuyển đổi loại tiềm ẩn.

trait HigherOrderFunctions[T, CC[_]] { 
    def zap[V](fn:() => V): CC[V] 
} 

class RichJList[T](list: java.util.List[T]) extends HigherOrderFunctions[T, java.util.List]{ 
    def zap[V](fn:() => V): java.util.List[V] = { 
     val l = new java.util.ArrayList[V] 
     l add fn() 
     l 
    } 
} 
implicit def list2RichList[T](l : java.util.List[T]) = new RichJList(l) 
new java.util.ArrayList[AnyRef]() zap (() => 2) 

Nếu trình biên dịch thấy rằng loại bỏ phương pháp zap nó sẽ chuyển nó sang một loại mà có phương pháp zap với một phương pháp chuyển đổi ngầm (ở đây list2RichList) trong phạm vi.

scala> new java.util.ArrayList[AnyRef]() zap (() => 2) 
res0: java.util.List[Int] = [2] 
Các vấn đề liên quan