Sorry in advance if I use the wrong terminology here.
What is the idiomatic way in Haskell to generalize two or more types so that you can defer pattern matching to them while avoiding the pattern?
To give a concrete example: in my application I want to convey possible errors that may occur at runtime. These errors relate to another module, so I do not directly control them:
data ErrorCatA = WTFError String | OMGError String data ErrorCatB = BadError Int | TerribleError Float
Now I want to convey some form of supertype of these error categories so that I can handle them as follows:
handleError :: GenericError -> IO () handleError err = putStrLn $ case err of WTFError s -> "WTF?! " ++ s OMGError s -> "OMG?! " ++ s BadError i -> if i > 5 then "Really bad" else "Not that bad" TerribleError f -> "Terrible! " ++ show f
Is it possible?
I got closest by creating this type of shell:
data GenericError = CatA ErrorCatA | CatB ErrorCatB class GError a where wrap :: a -> GenericError instance GError ErrorCatA where wrap = CatA instance GError ErrorCatB where wrap = CatB
Through this, I can easily transfer all errors, as in
handleError $ wrap $ WTFError "Woopsie"
but I will need to change handleError to match CatA (WTFError s) , etc.
Is there an easier or more idiomatic way to solve this scenario?
types haskell
passy
source share