{-# 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