{-# 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 test :: a -> Bool
test f :: a -> b
f val :: 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 def :: 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 def :: [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 def :: [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 def :: 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 def :: 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 def :: 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_ ys :: [a]
ys o :: Int
o
| Int
o Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
< 0 = [Char] -> Either [Char] a
forall a b. a -> Either a b
Left ("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 0 (x :: b
x:_) = b -> Either [Char] b
forall a b. b -> Either a b
Right b
x
f i :: Int
i (_:xs :: [b]
xs) = Int -> [b] -> Either [Char] b
f (Int
iInt -> Int -> Int
forall a. Num a => a -> a -> a
-1) [b]
xs
f i :: Int
i [] = [Char] -> Either [Char] b
forall a b. a -> Either a b
Left ("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]
++ ", 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 xs :: [a]
xs i :: Int
i = case [a]
xs [a] -> Int -> Either [Char] a
forall a. [a] -> Int -> Either [Char] a
`at_` Int
i of
Left _ -> Maybe a
forall a. Maybe a
Nothing
Right val :: a
val -> a -> Maybe a
forall a. a -> Maybe a
Just a
val
atDef :: a -> [a] -> Int -> a
atDef :: a -> [a] -> Int -> a
atDef def :: a
def xs :: [a]
xs i :: Int
i = case [a]
xs [a] -> Int -> Either [Char] a
forall a. [a] -> Int -> Either [Char] a
`at_` Int
i of
Left _ -> a
def
Right val :: a
val -> a
val