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.
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 []
.
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
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With