haskellpartial-functions

Can any partial function be converted to a total version in Haskell?


So far I have seen numerous "Maybe" versions of certain partial functions that would potentially result in ⊥, like readMaybe for read and listToMaybe for head; sometimes I wonder if we can generalise the idea and work out such a function safe :: (a -> b) -> (a -> Maybe b) to convert any partial function into their safer total alternative that returns Nothing on any instances where error stack would have been called in the original function. As till now I have not found a way to implement such safe function or existing implementations of a similar kind, and I come to doubt if this idea is truly viable.


Solution

  • There are two kinds of bottom actually, non-termination and error. You cannot catch non-termination, for obvious reasons, but you can catch errors. Here is a quickly thrown-together version (I am not an expert so there are probably better ways)

    {-# LANGUAGE ScopedTypeVariables #-}
    
    import Control.Exception
    import System.IO.Unsafe
    
    safe f = unsafePerformIO $ do
      z <- try (evaluate f)
      let r = case z of
         Left (e::SomeException) -> Nothing
         Right k -> Just k
      return r
    

    Here are some examples

    *Main > safe (head [42]) 
    Just 42
    *Main > safe (head []) 
    Nothing
    *Main λ safe (1 `div` 0)
    Nothing
    *Main λ safe (1 `div` 2)
    Just 0