Những vấn đề xuất phát từ val p = a*b
Nếu bạn viết đơn giản
cho (a < - (4) .right Ngay; b < - Phải (5) .right) mang a * b
nó biên dịch và bạn nhận được kết quả phù hợp.
Vấn đề của bạn có hai nguyên nhân
Thứ nhất, Either
dự map
và flatMap
không có chữ ký thông thường, cụ thể là cho bản đồ thói quen và flatMap định nghĩa trong một lớp generic M[A]
, (A => B) => M[B]
và (A => M[B]) => M[B]
. Các M[A]
các thói quen được định nghĩa là Either[A,B].RightProjection
, nhưng trong kết quả và đối số, chúng tôi có Either[A,B]
và không phải là chiếu.
Thứ hai, cách thức val p = a*b
trong bản dịch hiểu được dịch. Scala tham khảo, 6.19 p 90:
Một máy phát điện p < - e theo sau là một giá trị định nghĩa p '= e' là dịch sang các máy phát điện sau đây của cặp giá trị, trong đó x và x 'là những cái tên mới mẻ :
(p,p′) <- for([email protected]<-e) yield {val x′@p′ = e′; (x,x′)}
Hãy đơn giản hóa mã chỉ là một chút, thả a <-
. Ngoài ra, b
và p
được đổi tên thành p
và pp
để gần hơn với quy tắc ghi lại, với pp
cho p'
. a
phải nằm trong phạm vi cho (p < - sản lượng phải (5) .right; val pp = a * p) pp
theo quy tắc, chúng tôi phải thay thế định nghĩa của trình tạo +. Xung quanh đó, for(
và )yield pp
, không thay đổi.
for((p, pp) <- for([email protected] <- Right(5).right) yield{val [email protected] = a*p; (x,xx)}) yield pp
Các bên cho được viết lại với một bản đồ đơn giản
for((p, pp) <- Right(5).right.map{case [email protected] => val [email protected] = a*p; (x,xx)}) yield pp
Dưới đây là vấn đề. Right(5).right.map(...)
thuộc loại Either[Nothing, (Int,Int)]
, không phải Either.RightProjection[Nothing, (Int,Int)]
như chúng tôi muốn. Nó không hoạt động ở bên ngoài (cũng chuyển đổi thành map
.Không có phương pháp map
trên Either
, chỉ được xác định trên các phép chiếu.
Nếu bạn xem xét kỹ thông báo lỗi của mình, ngay cả khi nó đề cập đến Product
và Serializable
, nó nói rằng đó là Either[Nothing, (Int, Int)]
và không có bản đồ nào được xác định trên đó. Cặp (Int, Int)
xuất phát trực tiếp từ quy tắc viết lại.
Việc đọc hiểu được thiết kế để hoạt động tốt khi tôn trọng chữ ký thích hợp. Với thủ thuật với dự án Either
(cũng có những ưu điểm của nó), chúng tôi gặp phải vấn đề này.
Ah, điều đó bắt đầu có ý nghĩa. Bạn có một vài lỗi đánh lừa tôi lúc đầu (thiếu số nguyên tố, lỗi loại tinh tế, vv) mà tôi sẽ làm sạch ngay. – srparish
Kết quả thú vị ở trên là nếu tôi có loại monadic nhất quán, tôi sẽ ổn thôi. Vì vậy, nếu tôi chỉ quan tâm đến các dự đoán đúng, tôi có thể tạo ra một tiềm ẩn như sau đây thực sự khắc phục được vấn đề: deficit def RightProjection [A, B] (v: Hoặc [A, B]): Either.RightProjection [A, B] = v.right – srparish
Một lần nữa, cảm ơn rất lớn vì đã đăng ký toàn diện! Tôi đã đọc tài liệu tham khảo và vẫn chưa tìm ra chuyện gì đang diễn ra. Rõ ràng trong ví dụ đơn giản này, một * b có thể được chuyển đến sản lượng, nhưng nếu được thay thế bằng một phép tính phức tạp cần được chuyển đến hàm trả về một giá trị khác (lặp lại vài lần này), có thể sử dụng trung gian giá trị chuyển nhượng có thể được sạch hơn nhiều tìm kiếm sau đó phải có nhiều cấp độ của xích cho/báo cáo sản lượng. – srparish