2011-08-19 27 views
12

Để giúp tôi tìm hiểu Functors và Functors Ứng viên, tôi nghĩ sẽ rất thú vị khi xem cách Either được triển khai với typeclasses FunctorApplicative. Rõ ràng là tôi có thể tiếp tục đọc mã nhưng tôi thấy hữu ích hơn khi thử và thực hiện mọi thứ để hiểu rõ hơn về mọi thứ.Cố gắng triển khai Dữ liệu.Để

FYI Tôi đang cố gắng để thực hiện các phiên bản Haskell của các kết quả của báo cáo này http://applicative-errors-scala.googlecode.com/svn/artifacts/0.6/chunk-html/index.html

Dù sao, đây là những gì tôi có cho đến nay

data Validation a b = Success a | Failure b deriving (Show, Eq) 

instance Functor (Validation a) where 
    fmap f (Failure x) = Failure x 
    fmap f (Success x) = Success (f x) 

Nhưng bất cứ khi nào tôi cố gắng chạy này với ghci Tôi chỉ nhận được thông báo lỗi sau: -

[1 of 1] Compiling Main    (t.hs, interpreted) 

t.hs:5:35: 
    Couldn't match type `b' with `a1' 
     `b' is a rigid type variable bound by 
      the type signature for 
      fmap :: (a1 -> b) -> Validation a a1 -> Validation a b 
      at t.hs:4:5 
     `a1' is a rigid type variable bound by 
      the type signature for 
      fmap :: (a1 -> b) -> Validation a a1 -> Validation a b 
      at t.hs:4:5 
    Expected type: a 
     Actual type: b 
    In the return type of a call of `f' 
    In the first argument of `Success', namely `(f x)' 
    In the expression: Success (f x) 

t.hs:5:37: 
    Couldn't match type `a' with `a1' 
     `a' is a rigid type variable bound by 
      the instance declaration at t.hs:3:30 
     `a1' is a rigid type variable bound by 
      the type signature for 
      fmap :: (a1 -> b) -> Validation a a1 -> Validation a b 
      at t.hs:4:5 
    In the first argument of `f', namely `x' 
    In the first argument of `Success', namely `(f x)' 
    In the expression: Success 

Tôi không thực sự chắc chắn tại sao điều này là, bất cứ ai có thể giúp đỡ?

Trả lời

13

Bạn đang cố gắng để làm cho công việc Functor dụ trên Success phần, đó là điều bình thường để làm, nhưng vì thứ tự của các tham số kiểu của bạn nó đang được xác định trên gõ vào Failure phần để thay thế.

Vì bạn đã xác định nó như

data Validation a b = Success a | Failure b 

instance Functor (Validation a) where 
    ... 

Điều này có nghĩa rằng việc thực hiện lại fmap nên có các loại (x -> y) -> Validation a x -> Validation a y. Nhưng vì biến loại thứ hai là cho trường hợp Failure, điều này không gõ kiểm tra.

Bạn muốn kiểu biến đối với trường hợp Success là người cuối cùng thay vì:

data Validation b a = Success a | Failure b 
+0

Ahhh Tôi hiểu rồi, cảm ơn, tôi giả sử 'Validation dữ liệu a b = Failure a | Thành công b deriving (Show, Eq) 'cũng sẽ đúng. Cảm ơn! – djhworld

+1

@djworld: Đúng vậy. Đó chỉ là điều tương tự với tên của các biến kiểu và thứ tự của các nhà xây dựng được hoán đổi. – hammar

+5

@djhworld: Và bây giờ bạn cũng hiểu tại sao, trong 'Hoặc là b',' Trái' đại diện cho trường hợp lỗi (không chỉ vì nó không phải là kết quả "đúng"). –

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