    {-# LANGUAGE FlexibleContexts #-}
    {-# LANGUAGE ConstraintKinds  #-}
    {-# LANGUAGE CPP              #-}

    -- | Internal utilities.
    module Safe.Util(
        fromNoteModule, fromNoteEitherModule,
        liftMay,
        (.^), (.^^), (.^^^),
        eitherToMaybe,
        withFrozenCallStack
        ) where

    import Data.Maybe
    import Safe.Partial

    -- Let things work through ghci alone
    #if __GLASGOW_HASKELL__ >= 800
    import GHC.Stack
    #else
    withFrozenCallStack :: a -> a
    withFrozenCallStack = id
    #endif

    (.^) :: Partial => (b -> c) -> (a1 -> a2 -> b) -> a1 -> a2 -> c
    .^ :: forall b c a1 a2.
    Partial =>
    (b -> c) -> (a1 -> a2 -> b) -> a1 -> a2 -> c
    (.^) b -> c
    f a1 -> a2 -> b
    g a1
    x1 a2
    x2 = b -> c
    f (a1 -> a2 -> b
    g a1
    x1 a2
    x2)

    (.^^) :: Partial => (b -> c) -> (a1 -> a2 -> a3 -> b) -> a1 -> a2 -> a3 -> c
    .^^ :: forall b c a1 a2 a3.
    Partial =>
    (b -> c) -> (a1 -> a2 -> a3 -> b) -> a1 -> a2 -> a3 -> c
    (.^^) b -> c
    f a1 -> a2 -> a3 -> b
    g a1
    x1 a2
    x2 a3
    x3 = b -> c
    f (a1 -> a2 -> a3 -> b
    g a1
    x1 a2
    x2 a3
    x3)

    (.^^^) :: Partial => (b -> c) -> (a1 -> a2 -> a3 -> a4 -> b) -> a1 -> a2 -> a3 -> a4 -> c
    .^^^ :: forall b c a1 a2 a3 a4.
    Partial =>
    (b -> c)
    -> (a1 -> a2 -> a3 -> a4 -> b) -> a1 -> a2 -> a3 -> a4 -> c
    (.^^^) b -> c
    f a1 -> a2 -> a3 -> a4 -> b
    g a1
    x1 a2
    x2 a3
    x3 a4
    x4 = b -> c
    f (a1 -> a2 -> a3 -> a4 -> b
    g a1
    x1 a2
    x2 a3
    x3 a4
    x4)

    liftMay :: (a -> Bool) -> (a -> b) -> (a -> Maybe b)
    liftMay :: forall a b. (a -> Bool) -> (a -> b) -> a -> Maybe b
    liftMay a -> Bool
    test a -> b
    func a
    val = if a -> Bool
    test a
    val then Maybe b
    forall a. Maybe a
    Nothing else b -> Maybe b
    forall a. a -> Maybe a
    Just (b -> Maybe b) -> b -> Maybe b
    forall a b. (a -> b) -> a -> b
    $ a -> b
    func a
    val

    fromNoteModule :: Partial => String -> String -> String -> Maybe a -> a
    fromNoteModule :: forall a. Partial => String -> String -> String -> Maybe a -> a
    fromNoteModule String
    modu String
    note String
    func = a -> Maybe a -> a
    forall a. a -> Maybe a -> a
    fromMaybe (String -> a
    forall a. Partial => String -> a
    error String
    msg)
        where msg :: String
    msg = String
    modu String -> String -> String
    forall a. [a] -> [a] -> [a]
    ++ String
    "." String -> String -> String
    forall a. [a] -> [a] -> [a]
    ++ String
    func String -> String -> String
    forall a. [a] -> [a] -> [a]
    ++ (if String -> Bool
    forall a. [a] -> Bool
    forall (t :: * -> *) a. Foldable t => t a -> Bool
    null String
    note then String
    "" else String
    ", " String -> String -> String
    forall a. [a] -> [a] -> [a]
    ++ String
    note)

    fromNoteEitherModule :: Partial => String -> String -> String -> Either String a -> a
    fromNoteEitherModule :: forall a.
    Partial =>
    String -> String -> String -> Either String a -> a
    fromNoteEitherModule String
    modu String
    note String
    func = (String -> a) -> (a -> a) -> Either String a -> a
    forall a c b. (a -> c) -> (b -> c) -> Either a b -> c
    either (String -> a
    forall a. Partial => String -> a
    error (String -> a) -> (String -> String) -> String -> a
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . String -> String
    msg) a -> a
    forall a. a -> a
    id
        where msg :: String -> String
    msg String
    ex = String
    modu String -> String -> String
    forall a. [a] -> [a] -> [a]
    ++ String
    "." String -> String -> String
    forall a. [a] -> [a] -> [a]
    ++ String
    func String -> String -> String
    forall a. [a] -> [a] -> [a]
    ++ String
    " " String -> String -> String
    forall a. [a] -> [a] -> [a]
    ++ String
    ex String -> String -> String
    forall a. [a] -> [a] -> [a]
    ++ (if String -> Bool
    forall a. [a] -> Bool
    forall (t :: * -> *) a. Foldable t => t a -> Bool
    null String
    note then String
    "" else String
    ", " String -> String -> String
    forall a. [a] -> [a] -> [a]
    ++ String
    note)

    eitherToMaybe :: Either a b -> Maybe b
    eitherToMaybe :: forall a b. Either a b -> Maybe b
    eitherToMaybe = (a -> Maybe b) -> (b -> Maybe b) -> Either a b -> Maybe b
    forall a c b. (a -> c) -> (b -> c) -> Either a b -> c
    either (Maybe b -> a -> Maybe b
    forall a b. a -> b -> a
    const Maybe b
    forall a. Maybe a
    Nothing) b -> Maybe b
    forall a. a -> Maybe a
    Just