2012-09-05 55 views
5

Tôi quan tâm đến việc biết các quyết định thiết kế tại sao scala.Either không được thực hiện như một đơn nguyên. Hiện đã có một số cuộc thảo luận về cách phải xu hướng Either, ví dụ:Tại sao Scalas không phải là một đơn nguyên?

Nhưng có được đề cập quá nhiều chi tiết và tôi không thể có được một tổng quan đầy đủ về lý do tại sao nó được thực hiện khi nó được thực hiện. Ai đó có thể đưa ra một cái nhìn tổng quan về những lợi ích của việc có một thiên vị thích hợp Either, về các vấn đề để thực hiện theo cách đó và về lợi ích của việc không có thiên vị đúng Either (nếu chúng còn tồn tại)?

+0

Không thực sự trả lời câu hỏi, nhưng nếu bạn kiểm tra "Xác thực" của Scalaz có vẻ là thứ bạn đang tìm kiếm, nhiều hơn hoặc ít hơn. – adelbertc

Trả lời

7

Tôi nghĩ nó chỉ rơi xuống Principle of Least Astonishment. Sử dụng Either để mã hóa thành công hay thất bại rõ ràng là một cái gì đó mọi người làm, nhưng nó không phải là việc sử dụng duy nhất của Either. Trong thực tế, không có nhiều lý do để có Right là thành công và Left là thất bại khác với truyền thống. Như bình luận của adelbertc ở trên đề cập, scalaz có Validation mã hóa cụ thể điều này.

Để biện minh tiếp tục khẳng định POLA trên, lấy mã này:

def foo(): Either[Int, Int] = Right(1) 
def bar(j: Int): Either[Int, Int] = Left(1) 
def baz(z: Int): Either[Int, Int] = Right(3) 

// Result is Left(1) 
for (a <- foo().right; b <- bar(a).right; c <- baz(b).right) yield c 

này biên dịch bởi vì tôi đang sử dụng chiếu .right trong biểu thức for. Điều này có ý nghĩa ở đây là Left(1) trong bar là trường hợp lỗi và do đó, đó là kết quả, nhưng hãy tưởng tượng nếu EitherRight. Đoạn mã trên sẽ biên dịch mà không có sự .right dự báo trong biểu thức như:

for (a <- foo(); b <- bar(a); c <- baz(b)) yield c 

Nếu bạn sử dụng Either trong mã của bạn chỉ là một "một hoặc-the-khác" loại, bạn sẽ ngạc nhiên bởi (1) thực tế là điều này sẽ biên dịch và (2) nó trả về Left(1) và dường như không bao giờ thực hiện baz.

Tóm lại, sử dụng Validation nếu bạn muốn sử dụng Either để mã hóa thành công hay thất bại.

+0

+1 cho ví dụ ấn tượng. – Frank

5

Tôi không biết đây có phải là lý do ban đầu hay không, nhưng có ít nhất một lý do chính đáng. Trong Scala, for sự hiểu biết đòi hỏi nhiều hơn từ các đối số hơn là nó là một đơn nguyên để đạt được đầy đủ chức năng. Đặc biệt, có cấu trúc như

for (a <- ma if a > 7; /*...*/) yield /*...*/ 

mà yêu cầu các đơn nguyên là một đơn nguyên-với-zero (để bạn có thể làm rỗng nó nếu tình trạng này không thành công).

Either không thể hợp lý là một đơn nguyên không (tiết kiệm cho Either[Unit,B], trong đó Left(()) có thể là số không).

Có một cách để nói là: được rồi, tốt thôi, chỉ cần không sử dụng hiểu biết của bạn theo cách đó. Một cách khác để đi là nói: được rồi, không sao, đừng bận tâm làm gì cả. Đó là vấn đề sở thích cá nhân, tất nhiên, nhưng tôi có thể thấy sự thiếu thanh lịch khi có Either (duy nhất trong số các monads phổ biến được cung cấp trong Scala) rơi phẳng trên khuôn mặt của nó một khi bạn cố gắng sử dụng toàn bộ sức mạnh for cung cấp cho bạn.

Các vấn đề liên quan