{-# LANGUAGE BlockArguments, LambdaCase #-}
{-# OPTIONS_GHC -Wall -fno-warn-tabs #-}

module Data.Maybe.ToolsYj (
	forceJust, forceJust', orErrorIO, findMaybe, findMaybeM ) where

import Control.Exception

forceJust :: Exception e => e -> Maybe a -> a
forceJust :: forall e a. Exception e => e -> Maybe a -> a
forceJust e
e = a -> (a -> a) -> Maybe a -> a
forall b a. b -> (a -> b) -> Maybe a -> b
maybe (e -> a
forall a e. (HasCallStack, Exception e) => e -> a
throw e
e) a -> a
forall a. a -> a
id

forceJust' :: String -> Maybe a -> a
forceJust' :: forall a. String -> Maybe a -> a
forceJust' = ErrorCall -> Maybe a -> a
forall e a. Exception e => e -> Maybe a -> a
forceJust (ErrorCall -> Maybe a -> a)
-> (String -> ErrorCall) -> String -> Maybe a -> a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. String -> ErrorCall
ErrorCall

orErrorIO :: String -> Maybe a -> IO a
orErrorIO :: forall a. String -> Maybe a -> IO a
orErrorIO String
msg = IO a -> (a -> IO a) -> Maybe a -> IO a
forall b a. b -> (a -> b) -> Maybe a -> b
maybe (String -> IO a
forall a. HasCallStack => String -> a
error String
msg) a -> IO a
forall a. a -> IO a
forall (f :: * -> *) a. Applicative f => a -> f a
pure

findMaybe :: (a -> Maybe b) -> [a] -> Maybe (a, b)
findMaybe :: forall a b. (a -> Maybe b) -> [a] -> Maybe (a, b)
findMaybe a -> Maybe b
prd = \case
	[] -> Maybe (a, b)
forall a. Maybe a
Nothing
	a
p : [a]
ps -> ((Maybe b -> Maybe (a, b)) -> Maybe b -> Maybe (a, b)
forall a b. (a -> b) -> a -> b
$ a -> Maybe b
prd a
p) \case
		Maybe b
Nothing -> (a -> Maybe b) -> [a] -> Maybe (a, b)
forall a b. (a -> Maybe b) -> [a] -> Maybe (a, b)
findMaybe a -> Maybe b
prd [a]
ps; Just b
x -> (a, b) -> Maybe (a, b)
forall a. a -> Maybe a
Just (a
p, b
x)

findMaybeM :: Monad m => (a -> m (Maybe b)) -> [a] -> m (Maybe (a, b))
findMaybeM :: forall (m :: * -> *) a b.
Monad m =>
(a -> m (Maybe b)) -> [a] -> m (Maybe (a, b))
findMaybeM a -> m (Maybe b)
prd = \case
	[] -> Maybe (a, b) -> m (Maybe (a, b))
forall a. a -> m a
forall (f :: * -> *) a. Applicative f => a -> f a
pure Maybe (a, b)
forall a. Maybe a
Nothing
	a
p : [a]
ps -> a -> m (Maybe b)
prd a
p m (Maybe b) -> (Maybe b -> m (Maybe (a, b))) -> m (Maybe (a, b))
forall a b. m a -> (a -> m b) -> m b
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= \case
		Maybe b
Nothing -> (a -> m (Maybe b)) -> [a] -> m (Maybe (a, b))
forall (m :: * -> *) a b.
Monad m =>
(a -> m (Maybe b)) -> [a] -> m (Maybe (a, b))
findMaybeM a -> m (Maybe b)
prd [a]
ps; Just b
x -> Maybe (a, b) -> m (Maybe (a, b))
forall a. a -> m a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Maybe (a, b) -> m (Maybe (a, b)))
-> Maybe (a, b) -> m (Maybe (a, b))
forall a b. (a -> b) -> a -> b
$ (a, b) -> Maybe (a, b)
forall a. a -> Maybe a
Just (a
p, b
x)