Reputation: 9091
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.
Upvotes: 5
Views: 191
Reputation: 8937
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
Upvotes: 2
Reputation: 12077
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 []
.
Upvotes: 3