2012-01-27 15 views
14

Hãy nói rằng tôi có các bộ sau:một cách sạch sẽ để kết hợp hai bộ thành một tuple lớn hơn mới trong scala?

scala> val t1 = Tuple2("abcd", "efg") 
t1: (java.lang.String, java.lang.String) = (abcd,efg) 

scala> val t2 = Tuple2(1234, "lmnop") 
t2: (Int, java.lang.String) = (1234,lmnop) 

scala> val t3 = Tuple3("qrs", "tuv", "wxyz") 
t3: (java.lang.String, java.lang.String, java.lang.String) = (qrs,tuv,wxyz) 

Có một cách thân thiện để kết hợp chúng (theo hai bước nếu cần thiết) vào một Tuple7? Tôi thực sự đang tìm kiếm một câu trả lời chung cho việc kết hợp các bộ dữ liệu có kích thước tùy ý, và nhận ra rằng sẽ có những giới hạn do kích thước tuple tối đa được giới hạn. Tôi đặc biệt tìm kiếm một kết quả tuple, không phải là một bộ sưu tập.

+2

Check-out HLists các hình thức khác nhau: https://github.com/harrah/up http: //apocalisp.wordpress.com/2010/06/08/type-level-programming-in-scala/ http://stackoverflow.com/questions/8066654/covariance-in-type-level-programming/8067456#8067456 – Owen

Trả lời

14

Shapeless yêu cầu loại phương thức phụ thuộc (-Ydependent-method-types) và tôi muốn có một tệp nhị phân có thể tải xuống 2.9.1 để tôi có thể dùng thử nhưng thực sự có vẻ thanh lịch. Dựa trên this unit test nó sẽ áp dụng đối với trường hợp của bạn như thế này:

import shapeless.Tuples._ 
import shapeless.HList._ 
val t7 = (t1.hlisted ::: t2.hlisted ::: t3.hlisted).tupled 

Mặc dù Miles chỉ ra không có bảo lãnh của hỗ trợ, nó thực sự có kiểm tra đơn vị và nguồn là trên github với một giấy phép mã nguồn mở như vậy ít nhất nó không phải chỉ là một thử nghiệm trong một bài đăng trên blog.

Edit: làm việc như advertized - mất một thời gian để biên dịch và tôi đã có thêm -Xss1m để SBT:

$ scala -Ydependent-method-types -cp target/scala-2.9.1/shapeless_2.9.1-1.1.0.jar 
Welcome to Scala version 2.9.1.final (Java HotSpot(TM) Client VM, Java 1.7.0). 
Type in expressions to have them evaluated. 
Type :help for more information. 

scala> import shapeless.Tuples._ 
import shapeless.Tuples._ 

scala> import shapeless.HList._ 
import shapeless.HList._ 

scala> val t1 = Tuple2("abcd", "efg") 
t1: (java.lang.String, java.lang.String) = (abcd,efg) 

scala> val t2 = Tuple2(1234, "lmnop") 
t2: (Int, java.lang.String) = (1234,lmnop) 

scala> val t3 = Tuple3("qrs", "tuv", "wxyz") 
t3: (java.lang.String, java.lang.String, java.lang.String) = (qrs,tuv,wxyz) 

scala> (t1.hlisted ::: t2.hlisted ::: t3.hlisted).tupled 
res0: (java.lang.String, java.lang.String, Int, java.lang.String, java.lang.String, 
java.lang.String, java.lang.String) = (abcd,efg,1234,lmnop,qrs,tuv,wxyz) 
+0

Tại một thời điểm nào đó, tôi có lẽ sẽ pimp các hoạt động kiểu 'HList' trực tiếp lên các bộ dữ liệu, vì vậy bạn có thể bỏ qua shuffle/tupled và chỉ viết' t1 ::: t2 ::: t3'. Tôi đã vượt qua điều đó trên [topic/tuples branch] (https://github.com/milessabin/shapeless/tree/topic/tuples), nhưng trước khi tôi cam kết, tôi muốn chắc chắn rằng implicits không gây ra sự tàn phá. –

+0

Vâng, đây chính xác là những gì tôi đang tìm kiếm. Cảm ơn huynhjl cho trỏ nó ra và những việc để chứng minh rằng nó đáp ứng các câu hỏi, và nhờ Miles cho viết một gói mát mẻ như vậy! – jxstanford

5

Bạn thực sự cần sử dụng bộ sưu tập tại đây, đặc biệt nếu tất cả các phần tử đều có cùng loại. Bạn có thể kết hợp các bộ vào một List không mấy khó khăn:

def combine(xss: Product*) = xss.toList.flatten(_.productIterator) 

Sử dụng ví dụ của bạn:

scala> combine(t1, t2, t3) 
res1: List[Any] = List(abcd, efg, hijk, lmnop, qrs, tuv, wxyz) 

Đang cố gắng để tắt chức năng này trở lại vào tuples sẽ không làm việc bởi vì phương pháp chuyển đổi của bạn (ví dụ với mô hình phù hợp) sẽ không thể trả về loại tuple cụ thể (kiểu trả về của phương thức là gì?), và thông tin kiểu của mỗi phần tử đã bị mất.

+3

Tôi nên đưa ra một ví dụ tốt hơn. Không đảm bảo rằng tất cả các thành viên của bộ dữ liệu sẽ cùng loại, và tôi đang tìm kiếm một cách để có được bộ tuple mới. Trong những trường hợp khác, tôi sẽ sử dụng một bộ sưu tập, nhưng trong trường hợp này câu trả lời yêu cầu một bộ tuple. Tôi đã tinh chỉnh câu hỏi ... – jxstanford