Files
postgrest/src/Protolude/Safe.hs
T
Stephen DiehlandGitHub 2666f1e830 0.3 Release (#115)
* Add total ConvertText alternative to Conv

* Explain ConvertText's meaning

* Rename convertText to toS for compatibility

* 0.3.0 Refactor (#111)

* Begin work on 0.3 refactor

* Remove old docs folder

* Fix dodgy exports

* 4.8 constraint for null and length

* Guards for Semigroup export for base<4.9

* Fix Data.Bits exports

* Guards for typeable exports

* Remove unused pragmas

* Update hlint.yaml

* Use liftM because of pre-AMP quirkk

* Data.Char exports

* Rework Exception exports

* Fix bounds

* Adding Monad.Fail shim

* Fix displayException export

* Explicit GHC.Prim import for ancient ghc

* Explicit raise# for base-4.7

* Flush legacy testing infrastructure

* Update git location

* Update README

* Add Partial module

* Add concurrency exports

* Explicit GHC.Float exports

* Bounds for threadWaitReadSTM, threadWaitWriteSTM, forkOSWithUnmask

* Fix for weird undocumented underflowError weirdness

* forkOSWithUnask for base>4.8

* Fix GHC.Real exports pre base-4.7

* Fix withMVarMasked for base-4.7

* Update nix derivation

* Update derivation

* Update derivation

* Explicit functor exports

* <$ export

* Overwrite binary

* Fix some missing exports

* Update Changelog

* Minor export fixes base<4.9

* Explicit exports

* Export handler

* Generate export lists for multiple versions (#114)

* Generate export lists for #112

* Make export lists format OccName uniformly

* Make compile on ancient GHC

* Use Foldable.concat

* Hacks to make ghc-7.6 API happy

* liftIO shim

* Fix sortOn warning

* Update ChangeLog

* Update base bounds

* Export conventions

* Update Haddocks

* Document GHC magic
2020-01-24 11:06:09 +00:00

138 lines
3.7 KiB
Haskell

{-# 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 test f val = if test val then Nothing else Just (f val)
-------------------------------------------------------------------------------
-- Head
-------------------------------------------------------------------------------
headMay :: [a] -> Maybe a
headMay = liftMay null head
headDef :: a -> [a] -> a
headDef def = fromMaybe def . headMay
-------------------------------------------------------------------------------
-- Init
-------------------------------------------------------------------------------
initMay :: [a] -> Maybe [a]
initMay = liftMay null init
initDef :: [a] -> [a] -> [a]
initDef def = fromMaybe def . initMay
initSafe :: [a] -> [a]
initSafe = initDef []
-------------------------------------------------------------------------------
-- Tail
-------------------------------------------------------------------------------
tailMay :: [a] -> Maybe [a]
tailMay = liftMay null tail
tailDef :: [a] -> [a] -> [a]
tailDef def = fromMaybe def . tailMay
tailSafe :: [a] -> [a]
tailSafe = tailDef []
-------------------------------------------------------------------------------
-- Last
-------------------------------------------------------------------------------
lastMay :: [a] -> Maybe a
lastMay = liftMay null last
lastDef :: a -> [a] -> a
lastDef def = fromMaybe def . lastMay
-------------------------------------------------------------------------------
-- Maximum
-------------------------------------------------------------------------------
minimumMay, maximumMay :: Ord a => [a] -> Maybe a
minimumMay = liftMay null minimum
maximumMay = liftMay null maximum
minimumDef, maximumDef :: Ord a => a -> [a] -> a
minimumDef def = fromMaybe def . minimumMay
maximumDef def = fromMaybe def . maximumMay
-------------------------------------------------------------------------------
-- Foldr
-------------------------------------------------------------------------------
foldr1May, foldl1May, foldl1May' :: (a -> a -> a) -> [a] -> Maybe a
foldr1May = liftMay null . foldr1
-------------------------------------------------------------------------------
-- Foldl
-------------------------------------------------------------------------------
foldl1May = liftMay null . foldl1
foldl1May' = liftMay null . foldl1'
-------------------------------------------------------------------------------
-- At
-------------------------------------------------------------------------------
at_ :: [a] -> Int -> Either [Char] a
at_ ys o
| o < 0 = Left ("index must not be negative, index=" ++ show o)
| otherwise = f o ys
where
f 0 (x:_) = Right x
f i (_:xs) = f (i-1) xs
f i [] = Left ("index too large, index=" ++ show o ++ ", length=" ++ show (o-i))
atMay :: [a] -> Int -> Maybe a
atMay xs i = case xs `at_` i of
Left _ -> Nothing
Right val -> Just val
atDef :: a -> [a] -> Int -> a
atDef def xs i = case xs `at_` i of
Left _ -> def
Right val -> val