{-# LANGUAGE FlexibleContexts #-}
{-# LANGUAGE ConstraintKinds #-}
{-# LANGUAGE TupleSections #-}
module Safe.Exact(
takeExact, dropExact, splitAtExact,
zipExact, zipWithExact,
zip3Exact, zipWith3Exact,
takeExactMay, takeExactNote, takeExactDef,
dropExactMay, dropExactNote, dropExactDef,
splitAtExactMay, splitAtExactNote, splitAtExactDef,
zipExactMay, zipExactNote, zipExactDef,
zipWithExactMay, zipWithExactNote, zipWithExactDef,
zip3ExactMay, zip3ExactNote, zip3ExactDef,
zipWith3ExactMay, zipWith3ExactNote, zipWith3ExactDef,
) where
import Control.Arrow
import Data.Maybe
import Safe.Util
import Safe.Partial
addNote :: Partial => String -> String -> String -> a
addNote :: forall a. Partial => String -> String -> String -> a
addNote String
note String
fun String
msg = forall a. Partial => String -> a
error forall a b. (a -> b) -> a -> b
$
String
"Safe.Exact." forall a. [a] -> [a] -> [a]
++ String
fun forall a. [a] -> [a] -> [a]
++ String
", " forall a. [a] -> [a] -> [a]
++ String
msg forall a. [a] -> [a] -> [a]
++ (if forall (t :: * -> *) a. Foldable t => t a -> Bool
null String
note then String
"" else String
", " forall a. [a] -> [a] -> [a]
++ String
note)
{-# INLINE splitAtExact_ #-}
splitAtExact_ :: Partial => (String -> r) -> ([a] -> r) -> (a -> r -> r) -> Int -> [a] -> r
splitAtExact_ :: forall r a.
Partial =>
(String -> r) -> ([a] -> r) -> (a -> r -> r) -> Int -> [a] -> r
splitAtExact_ String -> r
err [a] -> r
nil a -> r -> r
cons Int
o [a]
xs
| Int
o forall a. Ord a => a -> a -> Bool
< Int
0 = String -> r
err forall a b. (a -> b) -> a -> b
$ String
"index must not be negative, index=" forall a. [a] -> [a] -> [a]
++ forall a. Show a => a -> String
show Int
o
| Bool
otherwise = Int -> [a] -> r
f Int
o [a]
xs
where
f :: Int -> [a] -> r
f Int
0 [a]
xs = [a] -> r
nil [a]
xs
f Int
i (a
x:[a]
xs) = a
x a -> r -> r
`cons` Int -> [a] -> r
f (Int
iforall a. Num a => a -> a -> a
-Int
1) [a]
xs
f Int
i [] = String -> r
err forall a b. (a -> b) -> a -> b
$ String
"index too large, index=" forall a. [a] -> [a] -> [a]
++ forall a. Show a => a -> String
show Int
o forall a. [a] -> [a] -> [a]
++ String
", length=" forall a. [a] -> [a] -> [a]
++ forall a. Show a => a -> String
show (Int
oforall a. Num a => a -> a -> a
-Int
i)
{-# INLINE zipWithExact_ #-}
zipWithExact_ :: Partial => (String -> r) -> r -> (a -> b -> r -> r) -> [a] -> [b] -> r
zipWithExact_ :: forall r a b.
Partial =>
(String -> r) -> r -> (a -> b -> r -> r) -> [a] -> [b] -> r
zipWithExact_ String -> r
err r
nil a -> b -> r -> r
cons = [a] -> [b] -> r
f
where
f :: [a] -> [b] -> r
f (a
x:[a]
xs) (b
y:[b]
ys) = a -> b -> r -> r
cons a
x b
y forall a b. (a -> b) -> a -> b
$ [a] -> [b] -> r
f [a]
xs [b]
ys
f [] [] = r
nil
f [] [b]
_ = String -> r
err String
"second list is longer than the first"
f [a]
_ [] = String -> r
err String
"first list is longer than the second"
{-# INLINE zipWith3Exact_ #-}
zipWith3Exact_ :: Partial => (String -> r) -> r -> (a -> b -> c -> r -> r) -> [a] -> [b] -> [c] -> r
zipWith3Exact_ :: forall r a b c.
Partial =>
(String -> r)
-> r -> (a -> b -> c -> r -> r) -> [a] -> [b] -> [c] -> r
zipWith3Exact_ String -> r
err r
nil a -> b -> c -> r -> r
cons = [a] -> [b] -> [c] -> r
f
where
f :: [a] -> [b] -> [c] -> r
f (a
x:[a]
xs) (b
y:[b]
ys) (c
z:[c]
zs) = a -> b -> c -> r -> r
cons a
x b
y c
z forall a b. (a -> b) -> a -> b
$ [a] -> [b] -> [c] -> r
f [a]
xs [b]
ys [c]
zs
f [] [] [] = r
nil
f [] [b]
_ [c]
_ = String -> r
err String
"first list is shorter than the others"
f [a]
_ [] [c]
_ = String -> r
err String
"second list is shorter than the others"
f [a]
_ [b]
_ [] = String -> r
err String
"third list is shorter than the others"
takeExact :: Partial => Int -> [a] -> [a]
takeExact :: forall a. Partial => Int -> [a] -> [a]
takeExact Int
i [a]
xs = forall a. Partial => (Partial => a) -> a
withFrozenCallStack forall a b. (a -> b) -> a -> b
$ forall r a.
Partial =>
(String -> r) -> ([a] -> r) -> (a -> r -> r) -> Int -> [a] -> r
splitAtExact_ (forall a. Partial => String -> String -> String -> a
addNote String
"" String
"takeExact") (forall a b. a -> b -> a
const []) (:) Int
i [a]
xs
dropExact :: Partial => Int -> [a] -> [a]
dropExact :: forall a. Partial => Int -> [a] -> [a]
dropExact Int
i [a]
xs = forall a. Partial => (Partial => a) -> a
withFrozenCallStack forall a b. (a -> b) -> a -> b
$ forall r a.
Partial =>
(String -> r) -> ([a] -> r) -> (a -> r -> r) -> Int -> [a] -> r
splitAtExact_ (forall a. Partial => String -> String -> String -> a
addNote String
"" String
"dropExact") forall a. a -> a
id (forall a b c. (a -> b -> c) -> b -> a -> c
flip forall a b. a -> b -> a
const) Int
i [a]
xs
splitAtExact :: Partial => Int -> [a] -> ([a], [a])
splitAtExact :: forall a. Partial => Int -> [a] -> ([a], [a])
splitAtExact Int
i [a]
xs = forall a. Partial => (Partial => a) -> a
withFrozenCallStack forall a b. (a -> b) -> a -> b
$ forall r a.
Partial =>
(String -> r) -> ([a] -> r) -> (a -> r -> r) -> Int -> [a] -> r
splitAtExact_ (forall a. Partial => String -> String -> String -> a
addNote String
"" String
"splitAtExact")
([],) (\a
a ([a], [a])
b -> forall (a :: * -> * -> *) b c d.
Arrow a =>
a b c -> a (b, d) (c, d)
first (a
aforall a. a -> [a] -> [a]
:) ([a], [a])
b) Int
i [a]
xs
takeExactNote :: Partial => String -> Int -> [a] -> [a]
takeExactNote :: forall a. Partial => String -> Int -> [a] -> [a]
takeExactNote String
note Int
i [a]
xs = forall a. Partial => (Partial => a) -> a
withFrozenCallStack forall a b. (a -> b) -> a -> b
$ forall r a.
Partial =>
(String -> r) -> ([a] -> r) -> (a -> r -> r) -> Int -> [a] -> r
splitAtExact_ (forall a. Partial => String -> String -> String -> a
addNote String
note String
"takeExactNote") (forall a b. a -> b -> a
const []) (:) Int
i [a]
xs
takeExactMay :: Int -> [a] -> Maybe [a]
takeExactMay :: forall a. Int -> [a] -> Maybe [a]
takeExactMay = forall r a.
Partial =>
(String -> r) -> ([a] -> r) -> (a -> r -> r) -> Int -> [a] -> r
splitAtExact_ (forall a b. a -> b -> a
const forall a. Maybe a
Nothing) (forall a b. a -> b -> a
const forall a b. (a -> b) -> a -> b
$ forall a. a -> Maybe a
Just []) (\a
a -> forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (a
aforall a. a -> [a] -> [a]
:))
takeExactDef :: [a] -> Int -> [a] -> [a]
takeExactDef :: forall a. [a] -> Int -> [a] -> [a]
takeExactDef [a]
def = forall a. a -> Maybe a -> a
fromMaybe [a]
def forall b c a1 a2.
Partial =>
(b -> c) -> (a1 -> a2 -> b) -> a1 -> a2 -> c
.^ forall a. Int -> [a] -> Maybe [a]
takeExactMay
dropExactNote :: Partial => String -> Int -> [a] -> [a]
dropExactNote :: forall a. Partial => String -> Int -> [a] -> [a]
dropExactNote String
note Int
i [a]
xs = forall a. Partial => (Partial => a) -> a
withFrozenCallStack forall a b. (a -> b) -> a -> b
$ forall r a.
Partial =>
(String -> r) -> ([a] -> r) -> (a -> r -> r) -> Int -> [a] -> r
splitAtExact_ (forall a. Partial => String -> String -> String -> a
addNote String
note String
"dropExactNote") forall a. a -> a
id (forall a b c. (a -> b -> c) -> b -> a -> c
flip forall a b. a -> b -> a
const) Int
i [a]
xs
dropExactMay :: Int -> [a] -> Maybe [a]
dropExactMay :: forall a. Int -> [a] -> Maybe [a]
dropExactMay = forall r a.
Partial =>
(String -> r) -> ([a] -> r) -> (a -> r -> r) -> Int -> [a] -> r
splitAtExact_ (forall a b. a -> b -> a
const forall a. Maybe a
Nothing) forall a. a -> Maybe a
Just (forall a b c. (a -> b -> c) -> b -> a -> c
flip forall a b. a -> b -> a
const)
dropExactDef :: [a] -> Int -> [a] -> [a]
dropExactDef :: forall a. [a] -> Int -> [a] -> [a]
dropExactDef [a]
def = forall a. a -> Maybe a -> a
fromMaybe [a]
def forall b c a1 a2.
Partial =>
(b -> c) -> (a1 -> a2 -> b) -> a1 -> a2 -> c
.^ forall a. Int -> [a] -> Maybe [a]
dropExactMay
splitAtExactNote :: Partial => String -> Int -> [a] -> ([a], [a])
splitAtExactNote :: forall a. Partial => String -> Int -> [a] -> ([a], [a])
splitAtExactNote String
note Int
i [a]
xs = forall a. Partial => (Partial => a) -> a
withFrozenCallStack forall a b. (a -> b) -> a -> b
$ forall r a.
Partial =>
(String -> r) -> ([a] -> r) -> (a -> r -> r) -> Int -> [a] -> r
splitAtExact_ (forall a. Partial => String -> String -> String -> a
addNote String
note String
"splitAtExactNote")
([],) (\a
a ([a], [a])
b -> forall (a :: * -> * -> *) b c d.
Arrow a =>
a b c -> a (b, d) (c, d)
first (a
aforall a. a -> [a] -> [a]
:) ([a], [a])
b) Int
i [a]
xs
splitAtExactMay :: Int -> [a] -> Maybe ([a], [a])
splitAtExactMay :: forall a. Int -> [a] -> Maybe ([a], [a])
splitAtExactMay = forall r a.
Partial =>
(String -> r) -> ([a] -> r) -> (a -> r -> r) -> Int -> [a] -> r
splitAtExact_ (forall a b. a -> b -> a
const forall a. Maybe a
Nothing)
(\[a]
x -> forall a. a -> Maybe a
Just ([], [a]
x)) (\a
a Maybe ([a], [a])
b -> forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (forall (a :: * -> * -> *) b c d.
Arrow a =>
a b c -> a (b, d) (c, d)
first (a
aforall a. a -> [a] -> [a]
:)) Maybe ([a], [a])
b)
splitAtExactDef :: ([a], [a]) -> Int -> [a] -> ([a], [a])
splitAtExactDef :: forall a. ([a], [a]) -> Int -> [a] -> ([a], [a])
splitAtExactDef ([a], [a])
def = forall a. a -> Maybe a -> a
fromMaybe ([a], [a])
def forall b c a1 a2.
Partial =>
(b -> c) -> (a1 -> a2 -> b) -> a1 -> a2 -> c
.^ forall a. Int -> [a] -> Maybe ([a], [a])
splitAtExactMay
zipExact :: Partial => [a] -> [b] -> [(a,b)]
zipExact :: forall a b. Partial => [a] -> [b] -> [(a, b)]
zipExact [a]
xs [b]
ys = forall a. Partial => (Partial => a) -> a
withFrozenCallStack forall a b. (a -> b) -> a -> b
$ forall r a b.
Partial =>
(String -> r) -> r -> (a -> b -> r -> r) -> [a] -> [b] -> r
zipWithExact_ (forall a. Partial => String -> String -> String -> a
addNote String
"" String
"zipExact") [] (\a
a b
b [(a, b)]
xs -> (a
a,b
b) forall a. a -> [a] -> [a]
: [(a, b)]
xs) [a]
xs [b]
ys
zipWithExact :: Partial => (a -> b -> c) -> [a] -> [b] -> [c]
zipWithExact :: forall a b c. Partial => (a -> b -> c) -> [a] -> [b] -> [c]
zipWithExact a -> b -> c
f [a]
xs [b]
ys = forall a. Partial => (Partial => a) -> a
withFrozenCallStack forall a b. (a -> b) -> a -> b
$ forall r a b.
Partial =>
(String -> r) -> r -> (a -> b -> r -> r) -> [a] -> [b] -> r
zipWithExact_ (forall a. Partial => String -> String -> String -> a
addNote String
"" String
"zipWithExact") [] (\a
a b
b [c]
xs -> a -> b -> c
f a
a b
b forall a. a -> [a] -> [a]
: [c]
xs) [a]
xs [b]
ys
zipExactNote :: Partial => String -> [a] -> [b] -> [(a,b)]
zipExactNote :: forall a b. Partial => String -> [a] -> [b] -> [(a, b)]
zipExactNote String
note [a]
xs [b]
ys = forall a. Partial => (Partial => a) -> a
withFrozenCallStack forall a b. (a -> b) -> a -> b
$ forall r a b.
Partial =>
(String -> r) -> r -> (a -> b -> r -> r) -> [a] -> [b] -> r
zipWithExact_ (forall a. Partial => String -> String -> String -> a
addNote String
note String
"zipExactNote") [] (\a
a b
b [(a, b)]
xs -> (a
a,b
b) forall a. a -> [a] -> [a]
: [(a, b)]
xs) [a]
xs [b]
ys
zipExactMay :: [a] -> [b] -> Maybe [(a,b)]
zipExactMay :: forall a b. [a] -> [b] -> Maybe [(a, b)]
zipExactMay = forall r a b.
Partial =>
(String -> r) -> r -> (a -> b -> r -> r) -> [a] -> [b] -> r
zipWithExact_ (forall a b. a -> b -> a
const forall a. Maybe a
Nothing) (forall a. a -> Maybe a
Just []) (\a
a b
b Maybe [(a, b)]
xs -> forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap ((a
a,b
b) forall a. a -> [a] -> [a]
:) Maybe [(a, b)]
xs)
zipExactDef :: [(a,b)] -> [a] -> [b] -> [(a,b)]
zipExactDef :: forall a b. [(a, b)] -> [a] -> [b] -> [(a, b)]
zipExactDef [(a, b)]
def = forall a. a -> Maybe a -> a
fromMaybe [(a, b)]
def forall b c a1 a2.
Partial =>
(b -> c) -> (a1 -> a2 -> b) -> a1 -> a2 -> c
.^ forall a b. [a] -> [b] -> Maybe [(a, b)]
zipExactMay
zipWithExactNote :: Partial => String -> (a -> b -> c) -> [a] -> [b] -> [c]
zipWithExactNote :: forall a b c.
Partial =>
String -> (a -> b -> c) -> [a] -> [b] -> [c]
zipWithExactNote String
note a -> b -> c
f [a]
xs [b]
ys = forall a. Partial => (Partial => a) -> a
withFrozenCallStack forall a b. (a -> b) -> a -> b
$ forall r a b.
Partial =>
(String -> r) -> r -> (a -> b -> r -> r) -> [a] -> [b] -> r
zipWithExact_ (forall a. Partial => String -> String -> String -> a
addNote String
note String
"zipWithExactNote") [] (\a
a b
b [c]
xs -> a -> b -> c
f a
a b
b forall a. a -> [a] -> [a]
: [c]
xs) [a]
xs [b]
ys
zipWithExactMay :: (a -> b -> c) -> [a] -> [b] -> Maybe [c]
zipWithExactMay :: forall a b c. (a -> b -> c) -> [a] -> [b] -> Maybe [c]
zipWithExactMay a -> b -> c
f = forall r a b.
Partial =>
(String -> r) -> r -> (a -> b -> r -> r) -> [a] -> [b] -> r
zipWithExact_ (forall a b. a -> b -> a
const forall a. Maybe a
Nothing) (forall a. a -> Maybe a
Just []) (\a
a b
b Maybe [c]
xs -> forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (a -> b -> c
f a
a b
b forall a. a -> [a] -> [a]
:) Maybe [c]
xs)
zipWithExactDef :: [c] -> (a -> b -> c) -> [a] -> [b] -> [c]
zipWithExactDef :: forall c a b. [c] -> (a -> b -> c) -> [a] -> [b] -> [c]
zipWithExactDef [c]
def = forall a. a -> Maybe a -> a
fromMaybe [c]
def forall b c a1 a2 a3.
Partial =>
(b -> c) -> (a1 -> a2 -> a3 -> b) -> a1 -> a2 -> a3 -> c
.^^ forall a b c. (a -> b -> c) -> [a] -> [b] -> Maybe [c]
zipWithExactMay
zip3Exact :: Partial => [a] -> [b] -> [c] -> [(a,b,c)]
zip3Exact :: forall a b c. Partial => [a] -> [b] -> [c] -> [(a, b, c)]
zip3Exact [a]
xs [b]
ys [c]
zs = forall a. Partial => (Partial => a) -> a
withFrozenCallStack forall a b. (a -> b) -> a -> b
$ forall r a b c.
Partial =>
(String -> r)
-> r -> (a -> b -> c -> r -> r) -> [a] -> [b] -> [c] -> r
zipWith3Exact_ (forall a. Partial => String -> String -> String -> a
addNote String
"" String
"zip3Exact") [] (\a
a b
b c
c [(a, b, c)]
xs -> (a
a, b
b, c
c) forall a. a -> [a] -> [a]
: [(a, b, c)]
xs) [a]
xs [b]
ys [c]
zs
zipWith3Exact :: Partial => (a -> b -> c -> d) -> [a] -> [b] -> [c] -> [d]
zipWith3Exact :: forall a b c d.
Partial =>
(a -> b -> c -> d) -> [a] -> [b] -> [c] -> [d]
zipWith3Exact a -> b -> c -> d
f [a]
xs [b]
ys [c]
zs = forall a. Partial => (Partial => a) -> a
withFrozenCallStack forall a b. (a -> b) -> a -> b
$ forall r a b c.
Partial =>
(String -> r)
-> r -> (a -> b -> c -> r -> r) -> [a] -> [b] -> [c] -> r
zipWith3Exact_ (forall a. Partial => String -> String -> String -> a
addNote String
"" String
"zipWith3Exact") [] (\a
a b
b c
c [d]
xs -> a -> b -> c -> d
f a
a b
b c
c forall a. a -> [a] -> [a]
: [d]
xs) [a]
xs [b]
ys [c]
zs
zip3ExactNote :: Partial => String -> [a] -> [b] -> [c]-> [(a,b,c)]
zip3ExactNote :: forall a b c. Partial => String -> [a] -> [b] -> [c] -> [(a, b, c)]
zip3ExactNote String
note [a]
xs [b]
ys [c]
zs = forall a. Partial => (Partial => a) -> a
withFrozenCallStack forall a b. (a -> b) -> a -> b
$ forall r a b c.
Partial =>
(String -> r)
-> r -> (a -> b -> c -> r -> r) -> [a] -> [b] -> [c] -> r
zipWith3Exact_ (forall a. Partial => String -> String -> String -> a
addNote String
note String
"zip3ExactNote") [] (\a
a b
b c
c [(a, b, c)]
xs -> (a
a,b
b,c
c) forall a. a -> [a] -> [a]
: [(a, b, c)]
xs) [a]
xs [b]
ys [c]
zs
zip3ExactMay :: [a] -> [b] -> [c] -> Maybe [(a,b,c)]
zip3ExactMay :: forall a b c. [a] -> [b] -> [c] -> Maybe [(a, b, c)]
zip3ExactMay = forall r a b c.
Partial =>
(String -> r)
-> r -> (a -> b -> c -> r -> r) -> [a] -> [b] -> [c] -> r
zipWith3Exact_ (forall a b. a -> b -> a
const forall a. Maybe a
Nothing) (forall a. a -> Maybe a
Just []) (\a
a b
b c
c Maybe [(a, b, c)]
xs -> forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap ((a
a,b
b,c
c) forall a. a -> [a] -> [a]
:) Maybe [(a, b, c)]
xs)
zip3ExactDef :: [(a,b,c)] -> [a] -> [b] -> [c] -> [(a,b,c)]
zip3ExactDef :: forall a b c. [(a, b, c)] -> [a] -> [b] -> [c] -> [(a, b, c)]
zip3ExactDef [(a, b, c)]
def = forall a. a -> Maybe a -> a
fromMaybe [(a, b, c)]
def forall b c a1 a2 a3.
Partial =>
(b -> c) -> (a1 -> a2 -> a3 -> b) -> a1 -> a2 -> a3 -> c
.^^ forall a b c. [a] -> [b] -> [c] -> Maybe [(a, b, c)]
zip3ExactMay
zipWith3ExactNote :: Partial => String -> (a -> b -> c -> d) -> [a] -> [b] -> [c] -> [d]
zipWith3ExactNote :: forall a b c d.
Partial =>
String -> (a -> b -> c -> d) -> [a] -> [b] -> [c] -> [d]
zipWith3ExactNote String
note a -> b -> c -> d
f [a]
xs [b]
ys [c]
zs = forall a. Partial => (Partial => a) -> a
withFrozenCallStack forall a b. (a -> b) -> a -> b
$ forall r a b c.
Partial =>
(String -> r)
-> r -> (a -> b -> c -> r -> r) -> [a] -> [b] -> [c] -> r
zipWith3Exact_ (forall a. Partial => String -> String -> String -> a
addNote String
note String
"zipWith3ExactNote") [] (\a
a b
b c
c [d]
xs -> a -> b -> c -> d
f a
a b
b c
c forall a. a -> [a] -> [a]
: [d]
xs) [a]
xs [b]
ys [c]
zs
zipWith3ExactMay :: (a -> b -> c -> d) -> [a] -> [b] -> [c] -> Maybe [d]
zipWith3ExactMay :: forall a b c d.
(a -> b -> c -> d) -> [a] -> [b] -> [c] -> Maybe [d]
zipWith3ExactMay a -> b -> c -> d
f = forall r a b c.
Partial =>
(String -> r)
-> r -> (a -> b -> c -> r -> r) -> [a] -> [b] -> [c] -> r
zipWith3Exact_ (forall a b. a -> b -> a
const forall a. Maybe a
Nothing) (forall a. a -> Maybe a
Just []) (\a
a b
b c
c Maybe [d]
xs -> forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (a -> b -> c -> d
f a
a b
b c
c forall a. a -> [a] -> [a]
:) Maybe [d]
xs)
zipWith3ExactDef :: [d] -> (a -> b -> c -> d) -> [a] -> [b] -> [c] -> [d]
zipWith3ExactDef :: forall d a b c.
[d] -> (a -> b -> c -> d) -> [a] -> [b] -> [c] -> [d]
zipWith3ExactDef [d]
def = forall a. a -> Maybe a -> a
fromMaybe [d]
def forall b c a1 a2 a3 a4.
Partial =>
(b -> c)
-> (a1 -> a2 -> a3 -> a4 -> b) -> a1 -> a2 -> a3 -> a4 -> c
.^^^ forall a b c d.
(a -> b -> c -> d) -> [a] -> [b] -> [c] -> Maybe [d]
zipWith3ExactMay