Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Safe application in Haskell

I have a piece of code where inside a list monad, a function is applied. Function may potentially have non-exhaustive pattern matching for its arguments. Therefore when the function is applied, I might get "Non-exhaustive pattern matching" error. I would like to turn this error into a monadic fail (in this case, an empty list). In other words I would like to get a similar behavior to what happens when Some Pattern Here <- some value inside a do block fails.

Question: Is there an efficient way to make a function application safe? By efficient I mean something that would be analogous to making the applied function match exhaustively and fail explicitly.

like image 713
julx Avatar asked Apr 01 '12 12:04

julx


2 Answers

One option would be to use spoon to convert the function from one that throws exceptions into one that returns Maybe a values. Then it should be a simple matter of converting Nothing to [].

like image 95
Daniel Pratt Avatar answered Sep 21 '22 13:09

Daniel Pratt


Hum, maybe with a catch? You should work in the IO monad however:

import Prelude hiding (catch)
import Control.Monad (MonadPlus, mzero)
import Control.Exception (catch, SomeException)

data B = T | F
    deriving (Show)

f :: B -> B
f T = F

justCatch :: (MonadPlus m) => a -> IO (m a)
justCatch x = catch (x `seq` (return . return) x) handler
  where
    handler :: (MonadPlus m) => SomeException -> IO (m a)
    handler _ = return mzero

I'm not sure about possible issues with this solution. At first sight it seems to work, but I would also like to read some opinions from knowledgeable Haskellers. I would not use this solution for sure in my code: an error should be treated as such, without hiding it.

*Main> justCatch $ f T :: IO [B]
[F]
*Main> justCatch $ f F :: IO [B]
[]
*Main> justCatch $ f F :: IO (Maybe B)
Nothing
*Main> justCatch $ f T :: IO (Maybe B)
Just F
*Main> f T
F
*Main> f F
*** Exception: except.hs:8:1-7: Non-exhaustive patterns in function Main.f
like image 35
Riccardo T. Avatar answered Sep 21 '22 13:09

Riccardo T.