    {-| This module extends the @safe@ library's functions with corresponding
        versions compatible with 'Either' and 'ExceptT', and also provides a few
        'Maybe'-compatible functions missing from @safe@.

        I suffix the 'Either'-compatible functions with @Err@ and prefix the
        'ExceptT'-compatible functions with @try@.

        Note that this library re-exports the 'Maybe' compatible functions from
        @safe@ in the "Control.Error" module, so they are not provided here.

        The \'@Z@\'-suffixed functions generalize the 'Maybe' functions to also work
        with anything that implements 'MonadPlus', including:

        * Lists

        * Most parsers

        * 'ExceptT' (if the left value is a 'Monoid')
    -}

    module Control.Error.Safe (
        -- * Maybe-compatible functions
        assertMay,
        rightMay,

        -- * Either-compatible functions
        tailErr,
        initErr,
        headErr,
        lastErr,
        minimumErr,
        maximumErr,
        foldr1Err,
        foldl1Err,
        foldl1Err',
        atErr,
        readErr,
        assertErr,
        justErr,

        -- * ExceptT-compatible functions
        tryTail,
        tryInit,
        tryHead,
        tryLast,
        tryMinimum,
        tryMaximum,
        tryFoldr1,
        tryFoldl1,
        tryFoldl1',
        tryAt,
        tryRead,
        tryAssert,
        tryJust,
        tryRight,

        -- * MonadPlus-compatible functions
        tailZ,
        initZ,
        headZ,
        lastZ,
        minimumZ,
        maximumZ,
        foldr1Z,
        foldl1Z,
        foldl1Z',
        atZ,
        readZ,
        assertZ,
        justZ,
        rightZ
        ) where

    import Control.Error.Util (note, hoistEither)
    import Control.Monad (MonadPlus(mzero))
    import Control.Monad.Trans.Except (ExceptT)
    import qualified Safe as S

    -- | An assertion that fails in the 'Maybe' monad
    assertMay :: Bool -> Maybe ()
    assertMay :: Bool -> Maybe ()
    assertMay = Bool -> Maybe ()
    forall (m :: * -> *). MonadPlus m => Bool -> m ()
    assertZ

    -- | A 'fromRight' that fails in the 'Maybe' monad
    rightMay :: Either e a -> Maybe a
    rightMay :: forall e a. Either e a -> Maybe a
    rightMay = Either e a -> Maybe a
    forall (m :: * -> *) e a. MonadPlus m => Either e a -> m a
    rightZ

    -- | A 'tail' that fails in the 'Either' monad
    tailErr :: e -> [a] -> Either e [a]
    tailErr :: forall e a. e -> [a] -> Either e [a]
    tailErr e
    e = e -> Maybe [a] -> Either e [a]
    forall a b. a -> Maybe b -> Either a b
    note e
    e (Maybe [a] -> Either e [a])
    -> ([a] -> Maybe [a]) -> [a] -> Either e [a]
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . [a] -> Maybe [a]
    forall a. [a] -> Maybe [a]
    S.tailMay

    -- | An 'init' that fails in the 'Either' monad
    initErr :: e -> [a] -> Either e [a]
    initErr :: forall e a. e -> [a] -> Either e [a]
    initErr e
    e = e -> Maybe [a] -> Either e [a]
    forall a b. a -> Maybe b -> Either a b
    note e
    e (Maybe [a] -> Either e [a])
    -> ([a] -> Maybe [a]) -> [a] -> Either e [a]
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . [a] -> Maybe [a]
    forall a. [a] -> Maybe [a]
    S.initMay

    -- | A 'head' that fails in the 'Either' monad
    headErr :: e -> [a] -> Either e a
    headErr :: forall e a. e -> [a] -> Either e a
    headErr e
    e = e -> Maybe a -> Either e a
    forall a b. a -> Maybe b -> Either a b
    note e
    e (Maybe a -> Either e a) -> ([a] -> Maybe a) -> [a] -> Either e a
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . [a] -> Maybe a
    forall a. [a] -> Maybe a
    S.headMay

    -- | A 'last' that fails in the 'Either' monad
    lastErr :: e -> [a] -> Either e a
    lastErr :: forall e a. e -> [a] -> Either e a
    lastErr e
    e = e -> Maybe a -> Either e a
    forall a b. a -> Maybe b -> Either a b
    note e
    e (Maybe a -> Either e a) -> ([a] -> Maybe a) -> [a] -> Either e a
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . [a] -> Maybe a
    forall a. [a] -> Maybe a
    S.lastMay

    -- | A 'minimum' that fails in the 'Either' monad
    minimumErr :: (Ord a) => e -> [a] -> Either e a
    minimumErr :: forall a e. Ord a => e -> [a] -> Either e a
    minimumErr e
    e = e -> Maybe a -> Either e a
    forall a b. a -> Maybe b -> Either a b
    note e
    e (Maybe a -> Either e a) -> ([a] -> Maybe a) -> [a] -> Either e a
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . [a] -> Maybe a
    forall a. Ord a => [a] -> Maybe a
    S.minimumMay

    -- | A 'maximum' that fails in the 'Either' monad
    maximumErr :: (Ord a) => e -> [a] -> Either e a
    maximumErr :: forall a e. Ord a => e -> [a] -> Either e a
    maximumErr e
    e = e -> Maybe a -> Either e a
    forall a b. a -> Maybe b -> Either a b
    note e
    e (Maybe a -> Either e a) -> ([a] -> Maybe a) -> [a] -> Either e a
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . [a] -> Maybe a
    forall a. Ord a => [a] -> Maybe a
    S.maximumMay

    -- | A 'foldr1' that fails in the 'Either' monad
    foldr1Err :: e -> (a -> a -> a) -> [a] -> Either e a
    foldr1Err :: forall e a. e -> (a -> a -> a) -> [a] -> Either e a
    foldr1Err e
    e a -> a -> a
    step [a]
    xs = e -> Maybe a -> Either e a
    forall a b. a -> Maybe b -> Either a b
    note e
    e (Maybe a -> Either e a) -> Maybe a -> Either e a
    forall a b. (a -> b) -> a -> b
    $ (a -> a -> a) -> [a] -> Maybe a
    forall a. (a -> a -> a) -> [a] -> Maybe a
    S.foldr1May a -> a -> a
    step [a]
    xs

    -- | A 'foldl1' that fails in the 'Either' monad
    foldl1Err :: e -> (a -> a -> a) -> [a] -> Either e a
    foldl1Err :: forall e a. e -> (a -> a -> a) -> [a] -> Either e a
    foldl1Err e
    e a -> a -> a
    step [a]
    xs = e -> Maybe a -> Either e a
    forall a b. a -> Maybe b -> Either a b
    note e
    e (Maybe a -> Either e a) -> Maybe a -> Either e a
    forall a b. (a -> b) -> a -> b
    $ (a -> a -> a) -> [a] -> Maybe a
    forall a. (a -> a -> a) -> [a] -> Maybe a
    S.foldl1May a -> a -> a
    step [a]
    xs

    -- | A 'foldl1'' that fails in the 'Either' monad
    foldl1Err' :: e -> (a -> a -> a) -> [a] -> Either e a
    foldl1Err' :: forall e a. e -> (a -> a -> a) -> [a] -> Either e a
    foldl1Err' e
    e a -> a -> a
    step [a]
    xs = e -> Maybe a -> Either e a
    forall a b. a -> Maybe b -> Either a b
    note e
    e (Maybe a -> Either e a) -> Maybe a -> Either e a
    forall a b. (a -> b) -> a -> b
    $ (a -> a -> a) -> [a] -> Maybe a
    forall a. (a -> a -> a) -> [a] -> Maybe a
    S.foldl1May' a -> a -> a
    step [a]
    xs

    -- | A ('!!') that fails in the 'Either' monad
    atErr :: e -> [a] -> Int -> Either e a
    atErr :: forall e a. e -> [a] -> Int -> Either e a
    atErr e
    e [a]
    xs Int
    n = e -> Maybe a -> Either e a
    forall a b. a -> Maybe b -> Either a b
    note e
    e (Maybe a -> Either e a) -> Maybe a -> Either e a
    forall a b. (a -> b) -> a -> b
    $ [a] -> Int -> Maybe a
    forall a. [a] -> Int -> Maybe a
    S.atMay [a]
    xs Int
    n

    -- | A 'read' that fails in the 'Either' monad
    readErr :: (Read a) => e -> String -> Either e a
    readErr :: forall a e. Read a => e -> String -> Either e a
    readErr e
    e = e -> Maybe a -> Either e a
    forall a b. a -> Maybe b -> Either a b
    note e
    e (Maybe a -> Either e a)
    -> (String -> Maybe a) -> String -> Either e a
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . String -> Maybe a
    forall a. Read a => String -> Maybe a
    S.readMay

    -- | An assertion that fails in the 'Either' monad
    assertErr :: e -> Bool -> Either e ()
    assertErr :: forall e. e -> Bool -> Either e ()
    assertErr e
    e Bool
    p = if Bool
    p then () -> Either e ()
    forall a b. b -> Either a b
    Right () else e -> Either e ()
    forall a b. a -> Either a b
    Left e
    e

    -- | A 'fromJust' that fails in the 'Either' monad
    justErr :: e -> Maybe a -> Either e a
    justErr :: forall a b. a -> Maybe b -> Either a b
    justErr e
    e = Either e a -> (a -> Either e a) -> Maybe a -> Either e a
    forall b a. b -> (a -> b) -> Maybe a -> b
    maybe (e -> Either e a
    forall a b. a -> Either a b
    Left e
    e) a -> Either e a
    forall a b. b -> Either a b
    Right

    -- | A 'tail' that fails in the 'ExceptT' monad
    tryTail :: (Monad m) => e -> [a] -> ExceptT e m [a]
    tryTail :: forall (m :: * -> *) e a. Monad m => e -> [a] -> ExceptT e m [a]
    tryTail e
    e [a]
    xs = Either e [a] -> ExceptT e m [a]
    forall (m :: * -> *) e a. Monad m => Either e a -> ExceptT e m a
    hoistEither (Either e [a] -> ExceptT e m [a])
    -> Either e [a] -> ExceptT e m [a]
    forall a b. (a -> b) -> a -> b
    $ e -> [a] -> Either e [a]
    forall e a. e -> [a] -> Either e [a]
    tailErr e
    e [a]
    xs

    -- | An 'init' that fails in the 'ExceptT' monad
    tryInit :: (Monad m) => e -> [a] -> ExceptT e m [a]
    tryInit :: forall (m :: * -> *) e a. Monad m => e -> [a] -> ExceptT e m [a]
    tryInit e
    e [a]
    xs = Either e [a] -> ExceptT e m [a]
    forall (m :: * -> *) e a. Monad m => Either e a -> ExceptT e m a
    hoistEither (Either e [a] -> ExceptT e m [a])
    -> Either e [a] -> ExceptT e m [a]
    forall a b. (a -> b) -> a -> b
    $ e -> [a] -> Either e [a]
    forall e a. e -> [a] -> Either e [a]
    initErr e
    e [a]
    xs

    -- | A 'head' that fails in the 'ExceptT' monad
    tryHead :: (Monad m) => e -> [a] -> ExceptT e m a
    tryHead :: forall (m :: * -> *) e a. Monad m => e -> [a] -> ExceptT e m a
    tryHead e
    e [a]
    xs = Either e a -> ExceptT e m a
    forall (m :: * -> *) e a. Monad m => Either e a -> ExceptT e m a
    hoistEither (Either e a -> ExceptT e m a) -> Either e a -> ExceptT e m a
    forall a b. (a -> b) -> a -> b
    $ e -> [a] -> Either e a
    forall e a. e -> [a] -> Either e a
    headErr e
    e [a]
    xs

    -- | A 'last' that fails in the 'ExceptT' monad
    tryLast :: (Monad m) => e -> [a] -> ExceptT e m a
    tryLast :: forall (m :: * -> *) e a. Monad m => e -> [a] -> ExceptT e m a
    tryLast e
    e [a]
    xs = Either e a -> ExceptT e m a
    forall (m :: * -> *) e a. Monad m => Either e a -> ExceptT e m a
    hoistEither (Either e a -> ExceptT e m a) -> Either e a -> ExceptT e m a
    forall a b. (a -> b) -> a -> b
    $ e -> [a] -> Either e a
    forall e a. e -> [a] -> Either e a
    lastErr e
    e [a]
    xs

    -- | A 'minimum' that fails in the 'ExceptT' monad
    tryMinimum :: (Monad m, Ord a) => e -> [a] -> ExceptT e m a
    tryMinimum :: forall (m :: * -> *) a e.
    (Monad m, Ord a) =>
    e -> [a] -> ExceptT e m a
    tryMinimum e
    e [a]
    xs = Either e a -> ExceptT e m a
    forall (m :: * -> *) e a. Monad m => Either e a -> ExceptT e m a
    hoistEither (Either e a -> ExceptT e m a) -> Either e a -> ExceptT e m a
    forall a b. (a -> b) -> a -> b
    $ e -> [a] -> Either e a
    forall a e. Ord a => e -> [a] -> Either e a
    maximumErr e
    e [a]
    xs

    -- | A 'maximum' that fails in the 'ExceptT' monad
    tryMaximum :: (Monad m, Ord a) => e -> [a] -> ExceptT e m a
    tryMaximum :: forall (m :: * -> *) a e.
    (Monad m, Ord a) =>
    e -> [a] -> ExceptT e m a
    tryMaximum e
    e [a]
    xs = Either e a -> ExceptT e m a
    forall (m :: * -> *) e a. Monad m => Either e a -> ExceptT e m a
    hoistEither (Either e a -> ExceptT e m a) -> Either e a -> ExceptT e m a
    forall a b. (a -> b) -> a -> b
    $ e -> [a] -> Either e a
    forall a e. Ord a => e -> [a] -> Either e a
    maximumErr e
    e [a]
    xs

    -- | A 'foldr1' that fails in the 'ExceptT' monad
    tryFoldr1 :: (Monad m) => e -> (a -> a -> a) -> [a] -> ExceptT e m a
    tryFoldr1 :: forall (m :: * -> *) e a.
    Monad m =>
    e -> (a -> a -> a) -> [a] -> ExceptT e m a
    tryFoldr1 e
    e a -> a -> a
    step [a]
    xs = Either e a -> ExceptT e m a
    forall (m :: * -> *) e a. Monad m => Either e a -> ExceptT e m a
    hoistEither (Either e a -> ExceptT e m a) -> Either e a -> ExceptT e m a
    forall a b. (a -> b) -> a -> b
    $ e -> (a -> a -> a) -> [a] -> Either e a
    forall e a. e -> (a -> a -> a) -> [a] -> Either e a
    foldr1Err e
    e a -> a -> a
    step [a]
    xs

    -- | A 'foldl1' that fails in the 'ExceptT' monad
    tryFoldl1 :: (Monad m) => e -> (a -> a -> a) -> [a] -> ExceptT e m a
    tryFoldl1 :: forall (m :: * -> *) e a.
    Monad m =>
    e -> (a -> a -> a) -> [a] -> ExceptT e m a
    tryFoldl1 e
    e a -> a -> a
    step [a]
    xs = Either e a -> ExceptT e m a
    forall (m :: * -> *) e a. Monad m => Either e a -> ExceptT e m a
    hoistEither (Either e a -> ExceptT e m a) -> Either e a -> ExceptT e m a
    forall a b. (a -> b) -> a -> b
    $ e -> (a -> a -> a) -> [a] -> Either e a
    forall e a. e -> (a -> a -> a) -> [a] -> Either e a
    foldl1Err e
    e a -> a -> a
    step [a]
    xs

    -- | A 'foldl1'' that fails in the 'ExceptT' monad
    tryFoldl1' :: (Monad m) => e -> (a -> a -> a) -> [a] -> ExceptT e m a
    tryFoldl1' :: forall (m :: * -> *) e a.
    Monad m =>
    e -> (a -> a -> a) -> [a] -> ExceptT e m a
    tryFoldl1' e
    e a -> a -> a
    step [a]
    xs = Either e a -> ExceptT e m a
    forall (m :: * -> *) e a. Monad m => Either e a -> ExceptT e m a
    hoistEither (Either e a -> ExceptT e m a) -> Either e a -> ExceptT e m a
    forall a b. (a -> b) -> a -> b
    $ e -> (a -> a -> a) -> [a] -> Either e a
    forall e a. e -> (a -> a -> a) -> [a] -> Either e a
    foldl1Err' e
    e a -> a -> a
    step [a]
    xs

    -- | A ('!!') that fails in the 'ExceptT' monad
    tryAt :: (Monad m) => e -> [a] -> Int -> ExceptT e m a
    tryAt :: forall (m :: * -> *) e a.
    Monad m =>
    e -> [a] -> Int -> ExceptT e m a
    tryAt e
    e [a]
    xs Int
    n = Either e a -> ExceptT e m a
    forall (m :: * -> *) e a. Monad m => Either e a -> ExceptT e m a
    hoistEither (Either e a -> ExceptT e m a) -> Either e a -> ExceptT e m a
    forall a b. (a -> b) -> a -> b
    $ e -> [a] -> Int -> Either e a
    forall e a. e -> [a] -> Int -> Either e a
    atErr e
    e [a]
    xs Int
    n

    -- | A 'read' that fails in the 'ExceptT' monad
    tryRead :: (Monad m, Read a) => e -> String -> ExceptT e m a
    tryRead :: forall (m :: * -> *) a e.
    (Monad m, Read a) =>
    e -> String -> ExceptT e m a
    tryRead e
    e String
    str = Either e a -> ExceptT e m a
    forall (m :: * -> *) e a. Monad m => Either e a -> ExceptT e m a
    hoistEither (Either e a -> ExceptT e m a) -> Either e a -> ExceptT e m a
    forall a b. (a -> b) -> a -> b
    $ e -> String -> Either e a
    forall a e. Read a => e -> String -> Either e a
    readErr e
    e String
    str

    -- | An assertion that fails in the 'ExceptT' monad
    tryAssert :: (Monad m) => e -> Bool -> ExceptT e m ()
    tryAssert :: forall (m :: * -> *) e. Monad m => e -> Bool -> ExceptT e m ()
    tryAssert e
    e Bool
    p = Either e () -> ExceptT e m ()
    forall (m :: * -> *) e a. Monad m => Either e a -> ExceptT e m a
    hoistEither (Either e () -> ExceptT e m ()) -> Either e () -> ExceptT e m ()
    forall a b. (a -> b) -> a -> b
    $ e -> Bool -> Either e ()
    forall e. e -> Bool -> Either e ()
    assertErr e
    e Bool
    p

    -- | A 'fromJust' that fails in the 'ExceptT' monad
    tryJust :: (Monad m) => e -> Maybe a -> ExceptT e m a
    tryJust :: forall (m :: * -> *) e a. Monad m => e -> Maybe a -> ExceptT e m a
    tryJust e
    e Maybe a
    m = Either e a -> ExceptT e m a
    forall (m :: * -> *) e a. Monad m => Either e a -> ExceptT e m a
    hoistEither (Either e a -> ExceptT e m a) -> Either e a -> ExceptT e m a
    forall a b. (a -> b) -> a -> b
    $ e -> Maybe a -> Either e a
    forall a b. a -> Maybe b -> Either a b
    justErr e
    e Maybe a
    m

    -- | A 'fromRight' that fails in the 'ExceptT' monad
    tryRight :: (Monad m) => Either e a -> ExceptT e m a
    tryRight :: forall (m :: * -> *) e a. Monad m => Either e a -> ExceptT e m a
    tryRight = Either e a -> ExceptT e m a
    forall (m :: * -> *) e a. Monad m => Either e a -> ExceptT e m a
    hoistEither

    -- | A 'tail' that fails using 'mzero'
    tailZ :: (MonadPlus m) => [a] -> m [a]
    tailZ :: forall (m :: * -> *) a. MonadPlus m => [a] -> m [a]
    tailZ = m [a] -> ([a] -> m [a]) -> Maybe [a] -> m [a]
    forall b a. b -> (a -> b) -> Maybe a -> b
    maybe m [a]
    forall a. m a
    forall (m :: * -> *) a. MonadPlus m => m a
    mzero [a] -> m [a]
    forall a. a -> m a
    forall (m :: * -> *) a. Monad m => a -> m a
    return (Maybe [a] -> m [a]) -> ([a] -> Maybe [a]) -> [a] -> m [a]
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . [a] -> Maybe [a]
    forall a. [a] -> Maybe [a]
    S.tailMay

    -- | An 'init' that fails using 'mzero'
    initZ :: (MonadPlus m) => [a] -> m [a]
    initZ :: forall (m :: * -> *) a. MonadPlus m => [a] -> m [a]
    initZ = m [a] -> ([a] -> m [a]) -> Maybe [a] -> m [a]
    forall b a. b -> (a -> b) -> Maybe a -> b
    maybe m [a]
    forall a. m a
    forall (m :: * -> *) a. MonadPlus m => m a
    mzero [a] -> m [a]
    forall a. a -> m a
    forall (m :: * -> *) a. Monad m => a -> m a
    return (Maybe [a] -> m [a]) -> ([a] -> Maybe [a]) -> [a] -> m [a]
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . [a] -> Maybe [a]
    forall a. [a] -> Maybe [a]
    S.initMay

    -- | A 'head' that fails using 'mzero'
    headZ :: (MonadPlus m) => [a] -> m a
    headZ :: forall (m :: * -> *) a. MonadPlus m => [a] -> m a
    headZ = m a -> (a -> m a) -> Maybe a -> m a
    forall b a. b -> (a -> b) -> Maybe a -> b
    maybe m a
    forall a. m a
    forall (m :: * -> *) a. MonadPlus m => m a
    mzero a -> m a
    forall a. a -> m a
    forall (m :: * -> *) a. Monad m => a -> m a
    return (Maybe a -> m a) -> ([a] -> Maybe a) -> [a] -> m a
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . [a] -> Maybe a
    forall a. [a] -> Maybe a
    S.headMay

    -- | A 'last' that fails using 'mzero'
    lastZ :: (MonadPlus m) => [a] -> m a
    lastZ :: forall (m :: * -> *) a. MonadPlus m => [a] -> m a
    lastZ = m a -> (a -> m a) -> Maybe a -> m a
    forall b a. b -> (a -> b) -> Maybe a -> b
    maybe m a
    forall a. m a
    forall (m :: * -> *) a. MonadPlus m => m a
    mzero a -> m a
    forall a. a -> m a
    forall (m :: * -> *) a. Monad m => a -> m a
    return (Maybe a -> m a) -> ([a] -> Maybe a) -> [a] -> m a
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . [a] -> Maybe a
    forall a. [a] -> Maybe a
    S.lastMay

    -- | A 'minimum' that fails using 'mzero'
    minimumZ :: (MonadPlus m) => (Ord a) => [a] -> m a
    minimumZ :: forall (m :: * -> *) a. (MonadPlus m, Ord a) => [a] -> m a
    minimumZ = m a -> (a -> m a) -> Maybe a -> m a
    forall b a. b -> (a -> b) -> Maybe a -> b
    maybe m a
    forall a. m a
    forall (m :: * -> *) a. MonadPlus m => m a
    mzero a -> m a
    forall a. a -> m a
    forall (m :: * -> *) a. Monad m => a -> m a
    return (Maybe a -> m a) -> ([a] -> Maybe a) -> [a] -> m a
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . [a] -> Maybe a
    forall a. Ord a => [a] -> Maybe a
    S.minimumMay

    -- | A 'maximum' that fails using 'mzero'
    maximumZ :: (MonadPlus m) => (Ord a) => [a] -> m a
    maximumZ :: forall (m :: * -> *) a. (MonadPlus m, Ord a) => [a] -> m a
    maximumZ = m a -> (a -> m a) -> Maybe a -> m a
    forall b a. b -> (a -> b) -> Maybe a -> b
    maybe m a
    forall a. m a
    forall (m :: * -> *) a. MonadPlus m => m a
    mzero a -> m a
    forall a. a -> m a
    forall (m :: * -> *) a. Monad m => a -> m a
    return (Maybe a -> m a) -> ([a] -> Maybe a) -> [a] -> m a
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . [a] -> Maybe a
    forall a. Ord a => [a] -> Maybe a
    S.maximumMay

    -- | A 'foldr1' that fails using 'mzero'
    foldr1Z :: (MonadPlus m) => (a -> a -> a) -> [a] -> m a
    foldr1Z :: forall (m :: * -> *) a. MonadPlus m => (a -> a -> a) -> [a] -> m a
    foldr1Z a -> a -> a
    step [a]
    xs = m a -> (a -> m a) -> Maybe a -> m a
    forall b a. b -> (a -> b) -> Maybe a -> b
    maybe m a
    forall a. m a
    forall (m :: * -> *) a. MonadPlus m => m a
    mzero a -> m a
    forall a. a -> m a
    forall (m :: * -> *) a. Monad m => a -> m a
    return (Maybe a -> m a) -> Maybe a -> m a
    forall a b. (a -> b) -> a -> b
    $ (a -> a -> a) -> [a] -> Maybe a
    forall a. (a -> a -> a) -> [a] -> Maybe a
    S.foldr1May a -> a -> a
    step [a]
    xs

    -- | A 'foldl1' that fails using 'mzero'
    foldl1Z :: (MonadPlus m) => (a -> a -> a) -> [a] -> m a
    foldl1Z :: forall (m :: * -> *) a. MonadPlus m => (a -> a -> a) -> [a] -> m a
    foldl1Z a -> a -> a
    step [a]
    xs = m a -> (a -> m a) -> Maybe a -> m a
    forall b a. b -> (a -> b) -> Maybe a -> b
    maybe m a
    forall a. m a
    forall (m :: * -> *) a. MonadPlus m => m a
    mzero a -> m a
    forall a. a -> m a
    forall (m :: * -> *) a. Monad m => a -> m a
    return (Maybe a -> m a) -> Maybe a -> m a
    forall a b. (a -> b) -> a -> b
    $ (a -> a -> a) -> [a] -> Maybe a
    forall a. (a -> a -> a) -> [a] -> Maybe a
    S.foldl1May a -> a -> a
    step [a]
    xs

    -- | A 'foldl1'' that fails using 'mzero'
    foldl1Z' :: (MonadPlus m) => (a -> a -> a) -> [a] -> m a
    foldl1Z' :: forall (m :: * -> *) a. MonadPlus m => (a -> a -> a) -> [a] -> m a
    foldl1Z' a -> a -> a
    step [a]
    xs = m a -> (a -> m a) -> Maybe a -> m a
    forall b a. b -> (a -> b) -> Maybe a -> b
    maybe m a
    forall a. m a
    forall (m :: * -> *) a. MonadPlus m => m a
    mzero a -> m a
    forall a. a -> m a
    forall (m :: * -> *) a. Monad m => a -> m a
    return (Maybe a -> m a) -> Maybe a -> m a
    forall a b. (a -> b) -> a -> b
    $ (a -> a -> a) -> [a] -> Maybe a
    forall a. (a -> a -> a) -> [a] -> Maybe a
    S.foldl1May' a -> a -> a
    step [a]
    xs

    -- | A ('!!') that fails using 'mzero'
    atZ :: (MonadPlus m) => [a] -> Int -> m a
    atZ :: forall (m :: * -> *) a. MonadPlus m => [a] -> Int -> m a
    atZ [a]
    xs Int
    n = m a -> (a -> m a) -> Maybe a -> m a
    forall b a. b -> (a -> b) -> Maybe a -> b
    maybe m a
    forall a. m a
    forall (m :: * -> *) a. MonadPlus m => m a
    mzero a -> m a
    forall a. a -> m a
    forall (m :: * -> *) a. Monad m => a -> m a
    return (Maybe a -> m a) -> Maybe a -> m a
    forall a b. (a -> b) -> a -> b
    $ [a] -> Int -> Maybe a
    forall a. [a] -> Int -> Maybe a
    S.atMay [a]
    xs Int
    n

    -- | A 'read' that fails using 'mzero'
    readZ :: (MonadPlus m) => (Read a) => String -> m a
    readZ :: forall (m :: * -> *) a. (MonadPlus m, Read a) => String -> m a
    readZ = m a -> (a -> m a) -> Maybe a -> m a
    forall b a. b -> (a -> b) -> Maybe a -> b
    maybe m a
    forall a. m a
    forall (m :: * -> *) a. MonadPlus m => m a
    mzero a -> m a
    forall a. a -> m a
    forall (m :: * -> *) a. Monad m => a -> m a
    return (Maybe a -> m a) -> (String -> Maybe a) -> String -> m a
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . String -> Maybe a
    forall a. Read a => String -> Maybe a
    S.readMay

    -- | An assertion that fails using 'mzero'
    assertZ :: (MonadPlus m) => Bool -> m ()
    assertZ :: forall (m :: * -> *). MonadPlus m => Bool -> m ()
    assertZ Bool
    p = if Bool
    p then () -> m ()
    forall a. a -> m a
    forall (m :: * -> *) a. Monad m => a -> m a
    return () else m ()
    forall a. m a
    forall (m :: * -> *) a. MonadPlus m => m a
    mzero

    -- | A 'fromJust' that fails using 'mzero'
    justZ :: (MonadPlus m) => Maybe a -> m a
    justZ :: forall (m :: * -> *) a. MonadPlus m => Maybe a -> m a
    justZ = m a -> (a -> m a) -> Maybe a -> m a
    forall b a. b -> (a -> b) -> Maybe a -> b
    maybe m a
    forall a. m a
    forall (m :: * -> *) a. MonadPlus m => m a
    mzero a -> m a
    forall a. a -> m a
    forall (m :: * -> *) a. Monad m => a -> m a
    return

    -- | A 'fromRight' that fails using 'mzero'
    rightZ :: (MonadPlus m) => Either e a -> m a
    rightZ :: forall (m :: * -> *) e a. MonadPlus m => Either e a -> m a
    rightZ = (e -> m a) -> (a -> m a) -> Either e a -> m a
    forall a c b. (a -> c) -> (b -> c) -> Either a b -> c
    either (m a -> e -> m a
    forall a b. a -> b -> a
    const m a
    forall a. m a
    forall (m :: * -> *) a. MonadPlus m => m a
    mzero) a -> m a
    forall a. a -> m a
    forall (m :: * -> *) a. Monad m => a -> m a
    return