{-# LANGUAGE CPP #-}
{-# LANGUAGE Safe #-}
{-# LANGUAGE OverloadedStrings #-}
{-# LANGUAGE NoImplicitPrelude #-}
module Protolude.Safe (
headMay
, headDef
, initMay
, initDef
, initSafe
, tailMay
, tailDef
, tailSafe
, lastDef
, lastMay
, foldr1May
, foldl1May
, foldl1May'
, maximumMay
, minimumMay
, maximumDef
, minimumDef
, atMay
, atDef
) where
import Data.Ord (Ord, (<))
import Data.Int (Int)
import Data.Char (Char)
import Data.Bool (Bool, otherwise)
import Data.Maybe (Maybe(Nothing, Just), fromMaybe)
import Data.Either (Either(Left, Right))
import Data.Function ((.))
import Data.List (null, head, last, tail, init, maximum, minimum, foldr1, foldl1, foldl1', (++))
import GHC.Num ((-))
import GHC.Show (show)
liftMay :: (a -> Bool) -> (a -> b) -> (a -> Maybe b)
liftMay :: (a -> Bool) -> (a -> b) -> a -> Maybe b
liftMay a -> Bool
test a -> b
f 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 (a -> b
f a
val)
headMay :: [a] -> Maybe a
headMay :: [a] -> Maybe a
headMay = ([a] -> Bool) -> ([a] -> a) -> [a] -> Maybe a
forall a b. (a -> Bool) -> (a -> b) -> a -> Maybe b
liftMay [a] -> Bool
forall (t :: * -> *) a. Foldable t => t a -> Bool
null [a] -> a
forall a. [a] -> a
head
headDef :: a -> [a] -> a
headDef :: a -> [a] -> a
headDef a
def = a -> Maybe a -> a
forall a. a -> Maybe a -> a
fromMaybe a
def (Maybe a -> a) -> ([a] -> Maybe a) -> [a] -> a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [a] -> Maybe a
forall a. [a] -> Maybe a
headMay
initMay :: [a] -> Maybe [a]
initMay :: [a] -> Maybe [a]
initMay = ([a] -> Bool) -> ([a] -> [a]) -> [a] -> Maybe [a]
forall a b. (a -> Bool) -> (a -> b) -> a -> Maybe b
liftMay [a] -> Bool
forall (t :: * -> *) a. Foldable t => t a -> Bool
null [a] -> [a]
forall a. [a] -> [a]
init
initDef :: [a] -> [a] -> [a]
initDef :: [a] -> [a] -> [a]
initDef [a]
def = [a] -> Maybe [a] -> [a]
forall a. a -> Maybe a -> a
fromMaybe [a]
def (Maybe [a] -> [a]) -> ([a] -> Maybe [a]) -> [a] -> [a]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [a] -> Maybe [a]
forall a. [a] -> Maybe [a]
initMay
initSafe :: [a] -> [a]
initSafe :: [a] -> [a]
initSafe = [a] -> [a] -> [a]
forall a. [a] -> [a] -> [a]
initDef []
tailMay :: [a] -> Maybe [a]
tailMay :: [a] -> Maybe [a]
tailMay = ([a] -> Bool) -> ([a] -> [a]) -> [a] -> Maybe [a]
forall a b. (a -> Bool) -> (a -> b) -> a -> Maybe b
liftMay [a] -> Bool
forall (t :: * -> *) a. Foldable t => t a -> Bool
null [a] -> [a]
forall a. [a] -> [a]
tail
tailDef :: [a] -> [a] -> [a]
tailDef :: [a] -> [a] -> [a]
tailDef [a]
def = [a] -> Maybe [a] -> [a]
forall a. a -> Maybe a -> a
fromMaybe [a]
def (Maybe [a] -> [a]) -> ([a] -> Maybe [a]) -> [a] -> [a]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [a] -> Maybe [a]
forall a. [a] -> Maybe [a]
tailMay
tailSafe :: [a] -> [a]
tailSafe :: [a] -> [a]
tailSafe = [a] -> [a] -> [a]
forall a. [a] -> [a] -> [a]
tailDef []
lastMay :: [a] -> Maybe a
lastMay :: [a] -> Maybe a
lastMay = ([a] -> Bool) -> ([a] -> a) -> [a] -> Maybe a
forall a b. (a -> Bool) -> (a -> b) -> a -> Maybe b
liftMay [a] -> Bool
forall (t :: * -> *) a. Foldable t => t a -> Bool
null [a] -> a
forall a. [a] -> a
last
lastDef :: a -> [a] -> a
lastDef :: a -> [a] -> a
lastDef a
def = a -> Maybe a -> a
forall a. a -> Maybe a -> a
fromMaybe a
def (Maybe a -> a) -> ([a] -> Maybe a) -> [a] -> a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [a] -> Maybe a
forall a. [a] -> Maybe a
lastMay
minimumMay, maximumMay :: Ord a => [a] -> Maybe a
minimumMay :: [a] -> Maybe a
minimumMay = ([a] -> Bool) -> ([a] -> a) -> [a] -> Maybe a
forall a b. (a -> Bool) -> (a -> b) -> a -> Maybe b
liftMay [a] -> Bool
forall (t :: * -> *) a. Foldable t => t a -> Bool
null [a] -> a
forall (t :: * -> *) a. (Foldable t, Ord a) => t a -> a
minimum
maximumMay :: [a] -> Maybe a
maximumMay = ([a] -> Bool) -> ([a] -> a) -> [a] -> Maybe a
forall a b. (a -> Bool) -> (a -> b) -> a -> Maybe b
liftMay [a] -> Bool
forall (t :: * -> *) a. Foldable t => t a -> Bool
null [a] -> a
forall (t :: * -> *) a. (Foldable t, Ord a) => t a -> a
maximum
minimumDef, maximumDef :: Ord a => a -> [a] -> a
minimumDef :: a -> [a] -> a
minimumDef a
def = a -> Maybe a -> a
forall a. a -> Maybe a -> a
fromMaybe a
def (Maybe a -> a) -> ([a] -> Maybe a) -> [a] -> a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [a] -> Maybe a
forall a. Ord a => [a] -> Maybe a
minimumMay
maximumDef :: a -> [a] -> a
maximumDef a
def = a -> Maybe a -> a
forall a. a -> Maybe a -> a
fromMaybe a
def (Maybe a -> a) -> ([a] -> Maybe a) -> [a] -> a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [a] -> Maybe a
forall a. Ord a => [a] -> Maybe a
maximumMay
foldr1May, foldl1May, foldl1May' :: (a -> a -> a) -> [a] -> Maybe a
foldr1May :: (a -> a -> a) -> [a] -> Maybe a
foldr1May = ([a] -> Bool) -> ([a] -> a) -> [a] -> Maybe a
forall a b. (a -> Bool) -> (a -> b) -> a -> Maybe b
liftMay [a] -> Bool
forall (t :: * -> *) a. Foldable t => t a -> Bool
null (([a] -> a) -> [a] -> Maybe a)
-> ((a -> a -> a) -> [a] -> a) -> (a -> a -> a) -> [a] -> Maybe a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (a -> a -> a) -> [a] -> a
forall (t :: * -> *) a. Foldable t => (a -> a -> a) -> t a -> a
foldr1
foldl1May :: (a -> a -> a) -> [a] -> Maybe a
foldl1May = ([a] -> Bool) -> ([a] -> a) -> [a] -> Maybe a
forall a b. (a -> Bool) -> (a -> b) -> a -> Maybe b
liftMay [a] -> Bool
forall (t :: * -> *) a. Foldable t => t a -> Bool
null (([a] -> a) -> [a] -> Maybe a)
-> ((a -> a -> a) -> [a] -> a) -> (a -> a -> a) -> [a] -> Maybe a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (a -> a -> a) -> [a] -> a
forall (t :: * -> *) a. Foldable t => (a -> a -> a) -> t a -> a
foldl1
foldl1May' :: (a -> a -> a) -> [a] -> Maybe a
foldl1May' = ([a] -> Bool) -> ([a] -> a) -> [a] -> Maybe a
forall a b. (a -> Bool) -> (a -> b) -> a -> Maybe b
liftMay [a] -> Bool
forall (t :: * -> *) a. Foldable t => t a -> Bool
null (([a] -> a) -> [a] -> Maybe a)
-> ((a -> a -> a) -> [a] -> a) -> (a -> a -> a) -> [a] -> Maybe a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (a -> a -> a) -> [a] -> a
forall a. (a -> a -> a) -> [a] -> a
foldl1'
at_ :: [a] -> Int -> Either [Char] a
at_ :: [a] -> Int -> Either [Char] a
at_ [a]
ys Int
o
| Int
o Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
< Int
0 = [Char] -> Either [Char] a
forall a b. a -> Either a b
Left ([Char]
"index must not be negative, index=" [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ Int -> [Char]
forall a. Show a => a -> [Char]
show Int
o)
| Bool
otherwise = Int -> [a] -> Either [Char] a
forall b. Int -> [b] -> Either [Char] b
f Int
o [a]
ys
where
f :: Int -> [b] -> Either [Char] b
f Int
0 (b
x:[b]
_) = b -> Either [Char] b
forall a b. b -> Either a b
Right b
x
f Int
i (b
_:[b]
xs) = Int -> [b] -> Either [Char] b
f (Int
iInt -> Int -> Int
forall a. Num a => a -> a -> a
-Int
1) [b]
xs
f Int
i [] = [Char] -> Either [Char] b
forall a b. a -> Either a b
Left ([Char]
"index too large, index=" [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ Int -> [Char]
forall a. Show a => a -> [Char]
show Int
o [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ [Char]
", length=" [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ Int -> [Char]
forall a. Show a => a -> [Char]
show (Int
oInt -> Int -> Int
forall a. Num a => a -> a -> a
-Int
i))
atMay :: [a] -> Int -> Maybe a
atMay :: [a] -> Int -> Maybe a
atMay [a]
xs Int
i = case [a]
xs [a] -> Int -> Either [Char] a
forall a. [a] -> Int -> Either [Char] a
`at_` Int
i of
Left [Char]
_ -> Maybe a
forall a. Maybe a
Nothing
Right a
val -> a -> Maybe a
forall a. a -> Maybe a
Just a
val
atDef :: a -> [a] -> Int -> a
atDef :: a -> [a] -> Int -> a
atDef a
def [a]
xs Int
i = case [a]
xs [a] -> Int -> Either [Char] a
forall a. [a] -> Int -> Either [Char] a
`at_` Int
i of
Left [Char]
_ -> a
def
Right a
val -> a
val