'try' can decide when a program halts

185 views Asked by At

I have this function:

isUndefined :: () -> Bool    
isUndefined x = case unsafePerformIO $ (try (return $! x) :: IO (Either SomeException ())) of
                    Left _ -> True
                    Right _ -> False

then:

isUndefined () = False
isUndefined undefined = True

Solving the halting problem. Of course, this can be extended to other types too.

My question: how is this possible? Is Control.Exception.try really breaking things here?

1

There are 1 answers

2
chi On BEST ANSWER

Is Control.Exception.try really breaking things here?

unsafePerformIO is breaking things here. In GHC, undefined simply raises an exception rather than looping forever (which would be unhelpful). Exceptions are not meant to be caught in pure (non-IO) code -- indeed the type system indeed prevents you to attempt as much.

By using unsafe* functions, you are telling GHC "ignore everything, I know what I'm doing", and all the safety belts are now off. Do yourself a favour and pretend that unsafe* stuff does not exist.