2014-07-15 16 views
5

Tôi hiện đang chuyển một số mã từ kiểu Scala truyền thống sang Scalaz.Scalaz Bind [Seq] typeclass

Khá phổ biến thông qua hầu hết mã của tôi để sử dụng đặc điểm Seq trong chữ ký API được tiếp xúc của tôi chứ không phải là loại cụ thể (tức là Danh sách, Vector) trực tiếp. Tuy nhiên, điều này đặt ra một số vấn đề với Scalaz, vì nó không cung cấp khả năng thực hiện một kiểu chữ Bind [Seq].

ví dụ này sẽ làm việc một cách chính xác.

List(1,2,3,4) >>= bindOperation 

Nhưng điều này sẽ không

Seq(1,2,3,4) >>= bindOperation 

thất bại với lỗi could not find implicit value for parameter F0: scalaz.Bind[Seq]

Tôi giả định này là một quyết định thiết kế có chủ ý trong Scalaz - tuy nhiên không chắc chắn về ý định thực hành/tốt nhất về cách đặt trước .

Tôi có nên thay vì viết mã của tôi trực tiếp vào danh sách/Vector phù hợp thay vì sử dụng giao diện Seq linh hoạt hơn? Hoặc tôi nên chỉ đơn giản là xác định riêng của tôi [Seq] typeclass?

+1

Có một ví dụ đơn lẻ của 'IndexedSeq'. – rightfold

Trả lời

11

Thư viện bộ sưu tập thực hiện backflips để chứa subtyping: khi bạn sử dụng map trên một loại bộ sưu tập cụ thể (danh sách, bản đồ, vv), bạn sẽ (thường) nhận được cùng một loại trở lại. Nó quản lý việc này thông qua việc sử dụng an extremely complex inheritance hierarchy cùng với các loại lớp như CanBuildFrom. Nó được thực hiện công việc (ít nhất là cho là), nhưng sự phức tạp không cảm thấy rất nguyên tắc. Đó là một mớ hỗn độn. Rất nhiều người ghét nó.

Sự phức tạp nói chung là khá dễ dàng để tránh như một người sử dụng thư viện, nhưng đối với một nhà thiết kế thư viện đó là một cơn ác mộng. Nếu tôi cung cấp một bản sao đơn lẻ cho Seq, điều đó có nghĩa là tất cả các loại người dùng của tôi đều gặp phải sự phân cấp lên Seq mọi loại họ sử dụng một phép toán đơn điệu.

Mọi người trong nhóm có xu hướng không thích phân loại rất nhiều, vì vậy, phần lớn Scalaz vẫn ở quanh các nhánh của phân cấp— List, Vector, v.v.

Khi lần đầu tiên tôi bắt đầu sử dụng Scalaz, tôi đã viết rất nhiều mã tiện ích đã cố gắng cung cấp các trường hợp cho Seq, v.v ... và làm cho chúng có thể sử dụng được với CanBuildFrom. Sau đó, tôi dừng lại, và bây giờ tôi có xu hướng làm theo Scalaz chỉ bao giờ sử dụng List, Vector, Map, và Set trong mã của riêng tôi. Nếu bạn cam kết với "phong cách Scalaz", bạn cũng nên làm điều đó (hoặc thậm chí chấp nhận riêng của mình là IList của Scalaz, ISet, ==>>, v.v.). Mặc dù vậy, bạn sẽ không tìm thấy thỏa thuận rõ ràng về các phương pháp hay nhất và cả hai cách tiếp cận có thể được thực hiện để làm việc, vì vậy bạn sẽ chỉ cần thử nghiệm để tìm thấy những gì bạn thích.

+1

Đây có phải là lý do không, ví dụ: 'scalaz.NonEmptyList [T]' không phải là một kiểu con của 'Seq [T]'? – rightfold

+1

@rightfold: Vâng, và tôi sẽ không quá ngạc nhiên nếu 'NonEmptyList' trở thành bất biến một ngày nào đó, đó là một lý do khác không bị kẹt trong đầm lầy' Seq'. –