module Enumerate.Function.Extra
( module Enumerate.Function.Extra
, module Control.DeepSeq
, module Data.Semigroup
, module GHC.Generics
, module Data.Data
, module Control.Arrow
, module Data.Function
, module Data.List
, module Data.Foldable
) where
import Data.Semigroup (Semigroup)
import Control.DeepSeq (NFData(..), deepseq)
import Control.Monad.Catch (MonadThrow(..), SomeException(..))
import GHC.Generics (Generic)
import Data.Data (Data)
import Control.Arrow ((>>>),(<<<))
import System.IO.Unsafe (unsafePerformIO)
import Control.Exception (catches, throwIO, Handler(..), AsyncException, ArithException, ArrayException, ErrorCall, PatternMatchFail)
import Data.Function ((&))
import Data.List (intercalate)
import Data.Foldable (traverse_)
nothing :: (Monad m) => m ()
nothing = return ()
maybe2bool :: Maybe a -> Bool
maybe2bool = maybe False (const True)
either2maybe :: Either e a -> Maybe a
either2maybe = either (const Nothing) Just
either2bool :: Either e a -> Bool
either2bool = either (const False) (const True)
failed :: (MonadThrow m) => String -> m a
failed = throwM . userError
maybe2throw :: (a -> Maybe b) -> (forall m. MonadThrow m => a -> m b)
maybe2throw f = f >>> \case
Nothing -> failed "Nothing"
Just x -> return x
list2throw :: (a -> [b]) -> (forall m. MonadThrow m => a -> m b)
list2throw f = f >>> \case
[] -> failed "[]"
(x:_) -> return x
either2throw :: (a -> Either SomeException b) -> (forall m. MonadThrow m => a -> m b)
either2throw f = f >>> \case
Left e -> throwM e
Right x -> return x
throw2maybe :: (forall m. MonadThrow m => a -> m b) -> (a -> Maybe b)
throw2maybe = id
throw2either :: (forall m. MonadThrow m => a -> m b) -> (a -> Either SomeException b)
throw2either = id
throw2list :: (forall m. MonadThrow m => a -> m b) -> (a -> [b])
throw2list = id
totalizeFunction :: (NFData b, MonadThrow m) => (a -> b) -> (a -> m b)
totalizeFunction f = g
where g x = spoonWith defaultPartialityHandlers (f x)
defaultPartialityHandlers :: (MonadThrow m) => [Handler (m a)]
defaultPartialityHandlers =
[ Handler $ \(e :: AsyncException) -> throwIO e
, Handler $ \(e :: ArithException) -> return (throwM e)
, Handler $ \(e :: ArrayException) -> return (throwM e)
, Handler $ \(e :: ErrorCall) -> return (throwM e)
, Handler $ \(e :: PatternMatchFail) -> return (throwM e)
, Handler $ \(e :: SomeException) -> return (throwM e)
]
spoonWith :: (NFData a, MonadThrow m) => [Handler (m a)] -> a -> m a
spoonWith handlers a = unsafePerformIO $ do
(a `deepseq` (return `fmap` return a)) `catches` handlers
showsPrecWith :: (Show b) => String -> (a -> b) -> Int -> a -> ShowS
showsPrecWith stringFrom functionInto p x = showParen (p > 10) $
showString stringFrom . showString " " . shows (functionInto x)