to/fromException question [SOLVED]

Hi there, after a while, I’ve started studying Haskell again and now I’m on exception part

And my question is following: why if I do fromException with SomeException or ArithException I get the same answer "Just divide by zero"

x = toException DivideByZero

fromException @ArithException x   -- Just divide by zero
fromException @SomeException x    -- Just divide by zero

but if I write directly the same one code, I get Nothing with SomeException

x = toException DivideByZero

f :: Exception e => SomeException -> Maybe e
f = \ (SomeException e) -> cast e

f @ArithException x               -- Just divide by zero
f @SomeException x                -- Nothing

here are definitions

fromException :: Exception e => SomeException -> Maybe e
fromException (SomeException e) = cast e

f             :: Exception e => SomeException -> Maybe e
f = \ (SomeException e) -> cast e

maybe I missed something? but I’m truly can’t understand why is that

your answers, will help me in an immense way

sorry for English, if so - it’s not my native :frowning:

3 Likes

fromException :: Exception e => SomeException -> Maybe e is a method from the Exception typeclass. So the actual implementation is determined by the concrete type of e, the type into which we want to convert the SomeException argument.

fromException @ArithException will use the instance for ArithException, and fromException @SomeException will use the instance for SomeException.

The instance method for ArithException is much like your f function (it’s not immediately clear because it’s inherited from the default implementation for Exception).

However, the method for SomeException is much unlike f! It’s actually

instance Exception SomeException where
    fromException = Just

Why? Because a conversion from SomeException into SomeException is trivial and never fails. So we simply return the input SomeException wrapped in Just.

casting the contents of the SomeException like f tries to do won’t work in this case, because the value inside the SomeException is actually the ArithException! The cast will fail. SomeException is an (existentially quantified) wrapper.

5 Likes

thanks a lot, I’ve suspected something like that but I had vague feeling that I’m wrong

yeah, Indeed, I missed that part

fromException @SomeException -- :: Exception SomeException => SomeException -> Maybe SomeException
-- uses SomeException instance, returns SomeException wrapped in Just
-- Just divide by zero
fromException @ArithException -- :: Exception ArithException => SomeException -> Maybe ArithException
-- uses ArithException instance
-- Just divide by zero

catch my flying kiss :kiss: