Обработка ошибок в Haskell с помощью любой монады
-
09-09-2019 - |
Вопрос
У меня есть функция, которая проверяет, является ли тип подтипом другого типа:
st :: Monad m => Map String Type -- ^type environment
-> Set (Type, Type) -- ^assumed subtypes
-> (Type, Type) -- ^we are checking if lhs <: rhs
-> m (Set (Type, Type))
Я хочу заняться обработкой ошибок.У меня есть следующее определение:
instance Monad (Either String) where
return v = Right v
fail s = Left s
(Left s) >>= _ = Left s
(Right v) >>= f = f v
Иногда я могу выполнить обработку ошибок, обработав результат st как любой из них.Например, следующая функция работает и выдает мне сообщения, которые являются результатом вызова "fail" внутри st:
isSubType env cs t1 t2 = result where
result = case st env (S.empty) (t1, t2) of
Left msg -> Left msg
Right rel -> Right ()
Теперь я нахожусь внутри st и хочу вызвать его рекурсивно.По какой-то причине следующий код, вложенный глубоко в st:
let do_t1 rel t1 = case st env rel (t1, t2) of
Left msg -> fail $ printf "type %s in the union is not a subtype\
\ of the rhs, %s, because: %s" (renderType t1)
(renderType t2) (show msg)
Right rel -> return rel
Не проверяет тип, но выдает мне следующую ошибку:
No instance for (Monad (Either t))
arising from a use of `st'
at src/TypedJavaScript/Types.hs:386:24-42
Possible fix: add an instance declaration for (Monad (Either t))
Почему обработка результата st как Либо работает вне 'st', но не внутри?Как я могу изменить свой код таким образом, чтобы он работал и внутри?
Решение
Я думаю, проблема в том, что вы звоните show msg
где вы должны просто использовать msg
.В результате компилятор не может определить, что вы имели в виду Either String
;все, что он знает, это то, что у вас есть Either t
где ограничение Show t
удовлетворен.Замена show msg
с msg
нужно это исправить.