Haskell error handling with any monad

I have a function that checks if a type is a subtype of another type:

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

I want to perform error handling. I have the following definition:

 instance Monad (Either String) where return v = Right v fail s = Left s (Left s) >>= _ = Left s (Right v) >>= f = fv 

Sometimes I can do error handling, handling the result of st like any. For example, the following function works and receives messages that occur when calling "fail" inside st:

 isSubType env cs t1 t2 = result where result = case st env (S.empty) (t1, t2) of Left msg -> Left msg Right rel -> Right () 

Now I'm inside st, and I want to call it recursively. For some reason, the following code nested deep in 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 

Does not enter validation, but gives the following error:

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

Why is processing the result of st like Either working outside of 'st', but not inside? How can I change my code so that it also works inside?

+6
type-inference haskell monads error-handling
source share
1 answer

I think the problem is that you call show msg , where you should just use msg . As a result, the compiler cannot deduce what you meant by Either String ; all he knows is that you have Either t where the Show t constraint is satisfied. Replace show msg with msg should be fixed.

+5
source share

All Articles