module Acme.Safe where

import Acme.Dont

-- | Safely extract a value from a Just
safeFromJust :: Maybe a -> Maybe a
safeFromJust :: forall a. Maybe a -> Maybe a
safeFromJust Maybe a
Nothing = Maybe a
forall a. Maybe a
Nothing
safeFromJust (Just a
x) = a -> Maybe a
forall a. a -> Maybe a
Just a
x

-- | Safely extract a value from a Left
safeFromLeft :: Either a b -> Either a b
safeFromLeft :: forall a b. Either a b -> Either a b
safeFromLeft (Left a
x) = a -> Either a b
forall a b. a -> Either a b
Left a
x
safeFromLeft (Right b
x) = b -> Either a b
forall a b. b -> Either a b
Right b
x

-- | Safely doesn't perform IO with the help of acme-dont. Side-effects-free!
safePerformIO :: IO a -> Maybe (IO ())
safePerformIO :: forall a. IO a -> Maybe (IO ())
safePerformIO = IO () -> Maybe (IO ())
forall a. a -> Maybe a
Just (IO () -> Maybe (IO ()))
-> (IO a -> IO ()) -> IO a -> Maybe (IO ())
forall b c a. (b -> c) -> (a -> b) -> a -> c
. IO a -> IO ()
forall (f :: * -> *) a. Applicative f => f a -> f ()
don't
--safePerformIO launchMissiles = Nothing --ready for the upcoming function-pattern-matching

-- | Doesn't print the provided debug string. But it's 100% safe!
safeTrace :: String -> a -> Maybe (IO ())
safeTrace :: forall a. String -> a -> Maybe (IO ())
safeTrace String
s a
x = IO a -> Maybe (IO ())
forall a. IO a -> Maybe (IO ())
safePerformIO (IO a -> Maybe (IO ())) -> IO a -> Maybe (IO ())
forall a b. (a -> b) -> a -> b
$ do
                                    String -> IO ()
putStrLn String
s
                                    a -> IO a
forall a. a -> IO a
forall (m :: * -> *) a. Monad m => a -> m a
return a
x

-- | Safely converts a value from any type to any other type.
safeCoerce :: a -> Maybe b
safeCoerce :: forall a b. a -> Maybe b
safeCoerce a
_ = Maybe b
forall a. Maybe a
Nothing