2011-12-22 25 views
5

Tôi có biến thế đơn nguyên sau để xử lý lỗi trong Haskell.Mono Haskell và lỗi không yêu cầu chuỗi

instance (Monad m, Error e) => Monad (EitherT e m) where 
    return = EitherT . return . return 
    m >>= k = EitherT $ do 
      a <- runEitherT m 
      case a of 
       Left l -> return (Left l) 
       Right r -> runEitherT (k r) 
    fail = EitherT . return . Left . strMsg 

Nó hoạt động khá tốt, vì tôi có thể nhanh chóng Error với lớp tùy chỉnh và có phương tiện khá linh hoạt để xử lý lỗi. Tuy nhiên,

fail là một chút ngớ ngẩn, vì đó là loại String -> EitherT e m và giới hạn String có thể là một cách gây phiền nhiễu để tạo lỗi. Tôi kết thúc với một toàn bộ rất nhiều:

instance Error BazError where 
    strMsg "foo" = FooError -- oh look we have no error context 
    strMsg "bar" = BarError -- isn't that nice 

Những gì tôi muốn làm là tạo một hàm mới, như fail, đó là loại a -> e để tôi có thể loại bỏ các hạn chế (Error e). fail đặc biệt thuận tiện khi đơn nguyên đống bị lớn, như khi tôi kết thúc với

EitherT BazError (StateT [BazWarning] IO) Foo 

Có cách nào để tạo ra một hàm có hành vi tương tự như fail với một loại ít hạn chế? Hoặc là fail được triển khai bằng cách sử dụng phép thuật tối đen haskell?

+3

Có lẽ bạn chỉ nên tránh hoàn toàn 'thất bại', trừ khi bạn muốn tùy chỉnh hành vi trên các kết quả mẫu' do'-block không thành công. – ehird

Trả lời

7

Vâng, fail được gọi nếu bạn có sự cố khớp mẫu trong khối làm, như nếu bạn có kết quả là Just x <- somethingsomethingNothing. Ngoài ra, fail là một chức năng bình thường.

Đối với sự cố với strMsg "foo" = FooError v.v., throwError có cung cấp giao diện đẹp hơn cho trường hợp sử dụng của bạn không?

4

Bài viết này có thể hữu ích: http://blog.ezyang.com/2011/08/8-ways-to-report-errors-in-haskell-revisited/

EitherT của bạn là đã có trong thư viện chuẩn và gọi ErrorT. Xem tài liệu: http://hackage.haskell.org/packages/archive/mtl/latest/doc/html/Control-Monad-Error.html#t:ErrorT

fail là sự tò mò lịch sử hiện tại và có thể được coi là lỗi thiết kế, cùng với thiếu ràng buộc Functor a => Monad a. Nó chỉ là một tính năng gây tranh cãi để xử lý các đối sánh mẫu không thành công trong ký hiệu do.

là phương án thay thế phổ biến nhất cho fail, nhưng còn nhiều hơn nữa (xem bài viết).

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