2015-03-01 19 views
7

Tôi hiện đang đọc tuyệt vời "Tìm hiểu Bạn một Haskell cho Vương Tốt", và trong section about functors có là một ví dụ liên quan đến Either mà tôi không hiểu:Sự khác nhau giữa trái và phải

ghci> fmap (replicate 3) (Right "blah") 
Right ["blah","blah","blah"] 
ghci> fmap (replicate 3) (Left "foo") 
Left "foo" 

Tại sao sau này không phải là Left ["foo", "foo", "foo"]?

+3

Nếu bạn muốn các hành vi sau , [Hoặc là một bifunctor] (https://hackage.haskell.org/package/bifunctors-4.2/docs/Data-Bifunctor.html). – kqr

Trả lời

12

Nhà xây dựng Left trên Either được triển khai là "trường hợp lỗi". Giống như các functors khác, một khi giá trị thất bại này đi vào phương trình, nó ngăn cản bất kỳ tính toán thực sự nào xảy ra. Do đó, khi bạn áp dụng fmap cho Left "foo", ngay lập tức trả về cùng một giá trị "lỗi".

Bạn có thể thấy điều này bằng cách nhìn vào cách Either thực hiện fmap:

instance Functor (Either a) where 
    fmap f (Right x) = Right (f x) 
    fmap f (Left x) = Left x 

Ý tưởng ở đây là Left "foo" thực sự sẽ là một cái gì đó mô tả nhiều hơn, giống như Left "Value could not be computed". Nếu bạn cố gắng áp dụng các hàm khác cho giá trị đó, bạn chỉ muốn "lỗi" được truyền đi nguyên vẹn.

Nếu nó giúp, chỉ cần tưởng tượng như thế nào fmap sẽ làm việc trên một số loại khác, nơi các trường hợp thất bại là rõ ràng hơn, ví dụ:

-- Maybe: failure value is `Nothing` 
fmap (replicate 3) (Nothing) 

này tạo Nothing, không [Nothing, Nothing, Nothing]

+5

Cảm ơn bạn đã trả lời nhanh! Tôi đã hiểu hành vi 'Có thể'. Điều gì đã giúp tôi với 'Either' là tự nhắc nhở bản thân rằng không phải' Either' là một functor, nhưng 'Hoặc là a'! – mkrieger1

+0

@ mkrieger1 Một quy tắc ghi nhớ đơn giản để nhớ cái nào là: trường hợp 'Phải' là viết tắt của đúng/thành công /" đúng ", chữ" Trái "là viết tắt của" không đúng "do đó sai/sai/thất bại. – chi

+2

@chi .... và do đó bị bỏ lại một mình bởi bất kỳ phiên bản Functor/Applicative/Monad nào. – AndrewC

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