Advertisement
NLinker

tryAny test

Jul 28th, 2017
435
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. {-# LANGUAGE GeneralizedNewtypeDeriving #-}
  2. {-# LANGUAGE MultiParamTypeClasses      #-}
  3. {-# LANGUAGE TypeFamilies               #-}
  4.  
  5. module TestTryAny where
  6.  
  7. import           Control.Applicative          (Alternative, empty, (<|>))
  8. import           Control.Exception            (Exception, fromException, throwIO)
  9. import           Control.Exception.Enclosed   (tryAny, catchAny)
  10. import           Control.Monad.Base           (MonadBase)
  11. import           Control.Monad.IO.Class       (MonadIO, liftIO)
  12. import           Control.Monad.Trans.Control  (MonadBaseControl, StM, liftBaseWith, restoreM)
  13. import           Control.Monad.Trans.Resource ()
  14. import           Data.Typeable                (Typeable)
  15.  
  16. -- Explore tryAny behavior, transformers and MonadBaseControl
  17.  
  18. data IOAlternativeEmpty = IOAlternativeEmpty deriving (Typeable, Show)
  19.  
  20. instance Exception IOAlternativeEmpty
  21.  
  22. newtype MyIO a = MyIO { runMyIO :: IO a }
  23.   deriving (Functor, Applicative, Monad, MonadIO, MonadBase IO)
  24.  
  25. instance MonadBaseControl IO MyIO where
  26.   type StM MyIO a = a
  27.   liftBaseWith f = liftIO $ f runMyIO
  28.   restoreM = return
  29.   {-# INLINABLE liftBaseWith #-}
  30.   {-# INLINABLE restoreM #-}
  31.  
  32. instance Alternative MyIO where
  33.     empty = liftIO $ throwIO IOAlternativeEmpty
  34.     x <|> y = x `catchAny` \xe ->
  35.         y `catchAny` \ye -> case fromException ye of
  36.             Just IOAlternativeEmpty -> liftIO $ throwIO xe
  37.             _ -> liftIO $ throwIO ye
  38.  
  39. testThis :: IO ()
  40. testThis = runMyIO $ liftIO $ do
  41.     print =<< tryAny (putStrLn "one" <|> putStrLn "two")
  42.     print =<< tryAny (error "oops" <|> putStrLn "two")
  43.     print =<< tryAny (error "oops" <|> error "here" :: IO ())
  44.     print =<< tryAny (putStrLn "one" <|> empty)
  45.     print =<< tryAny (empty <|> putStrLn "two")
  46.     print =<< tryAny (empty <|> empty :: IO ())
  47.     print =<< tryAny (error "oops" <|> empty :: IO ())
  48.     print =<< tryAny (empty <|> error "here" :: IO ())
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement