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?
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