-- | Operations on lists, generated to an arbitrary generating equality
module System.FilePattern.ListBy(
    eqListBy, stripPrefixBy, stripSuffixBy, stripInfixBy
    ) where

import Control.Applicative
import Data.Tuple.Extra


eqListBy :: (a -> b -> Maybe c) -> [a] -> [b] -> Maybe [c]
eqListBy :: (a -> b -> Maybe c) -> [a] -> [b] -> Maybe [c]
eqListBy a -> b -> Maybe c
_ [] [] = [c] -> Maybe [c]
forall a. a -> Maybe a
Just []
eqListBy a -> b -> Maybe c
eq (a
a:[a]
as) (b
b:[b]
bs) = (c -> [c] -> [c]) -> Maybe c -> Maybe [c] -> Maybe [c]
forall (f :: * -> *) a b c.
Applicative f =>
(a -> b -> c) -> f a -> f b -> f c
liftA2 (:) (a -> b -> Maybe c
eq a
a b
b) ((a -> b -> Maybe c) -> [a] -> [b] -> Maybe [c]
forall a b c. (a -> b -> Maybe c) -> [a] -> [b] -> Maybe [c]
eqListBy a -> b -> Maybe c
eq [a]
as [b]
bs)
eqListBy a -> b -> Maybe c
_ [a]
_ [b]
_ = Maybe [c]
forall a. Maybe a
Nothing


stripPrefixBy :: (a -> b -> Maybe c) -> [a] -> [b] -> Maybe ([c], [b])
stripPrefixBy :: (a -> b -> Maybe c) -> [a] -> [b] -> Maybe ([c], [b])
stripPrefixBy a -> b -> Maybe c
eq [] [b]
bs = ([c], [b]) -> Maybe ([c], [b])
forall a. a -> Maybe a
Just ([], [b]
bs)
stripPrefixBy a -> b -> Maybe c
eq [a]
_  [] = Maybe ([c], [b])
forall a. Maybe a
Nothing
stripPrefixBy a -> b -> Maybe c
eq (a
a:[a]
as) (b
b:[b]
bs) = do c
c <- a -> b -> Maybe c
eq a
a b
b; ([c] -> [c]) -> ([c], [b]) -> ([c], [b])
forall a a' b. (a -> a') -> (a, b) -> (a', b)
first (c
cc -> [c] -> [c]
forall a. a -> [a] -> [a]
:) (([c], [b]) -> ([c], [b])) -> Maybe ([c], [b]) -> Maybe ([c], [b])
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> (a -> b -> Maybe c) -> [a] -> [b] -> Maybe ([c], [b])
forall a b c. (a -> b -> Maybe c) -> [a] -> [b] -> Maybe ([c], [b])
stripPrefixBy a -> b -> Maybe c
eq [a]
as [b]
bs

stripSuffixBy :: (a -> b -> Maybe c) -> [a] -> [b] -> Maybe ([b], [c])
stripSuffixBy :: (a -> b -> Maybe c) -> [a] -> [b] -> Maybe ([b], [c])
stripSuffixBy a -> b -> Maybe c
eq [] [b]
bs = ([b], [c]) -> Maybe ([b], [c])
forall a. a -> Maybe a
Just ([b]
bs, []) -- shortcut, but equal to the equation below
stripSuffixBy a -> b -> Maybe c
eq [a]
_  [] = Maybe ([b], [c])
forall a. Maybe a
Nothing       -- shortcut, but equal to the equation below
stripSuffixBy a -> b -> Maybe c
eq [a]
as [b]
bs = (\([c]
c,[b]
b) -> ([b] -> [b]
forall a. [a] -> [a]
reverse [b]
b, [c] -> [c]
forall a. [a] -> [a]
reverse [c]
c)) (([c], [b]) -> ([b], [c])) -> Maybe ([c], [b]) -> Maybe ([b], [c])
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> (a -> b -> Maybe c) -> [a] -> [b] -> Maybe ([c], [b])
forall a b c. (a -> b -> Maybe c) -> [a] -> [b] -> Maybe ([c], [b])
stripPrefixBy a -> b -> Maybe c
eq ([a] -> [a]
forall a. [a] -> [a]
reverse [a]
as) ([b] -> [b]
forall a. [a] -> [a]
reverse [b]
bs)

stripInfixBy :: (a -> b -> Maybe c) -> [a] -> [b] -> Maybe ([b], [c], [b])
stripInfixBy :: (a -> b -> Maybe c) -> [a] -> [b] -> Maybe ([b], [c], [b])
stripInfixBy a -> b -> Maybe c
eq [a]
needle [b]
haystack | Just ([c]
ans, [b]
rest) <- (a -> b -> Maybe c) -> [a] -> [b] -> Maybe ([c], [b])
forall a b c. (a -> b -> Maybe c) -> [a] -> [b] -> Maybe ([c], [b])
stripPrefixBy a -> b -> Maybe c
eq [a]
needle [b]
haystack = ([b], [c], [b]) -> Maybe ([b], [c], [b])
forall a. a -> Maybe a
Just ([], [c]
ans, [b]
rest)
stripInfixBy a -> b -> Maybe c
eq [a]
needle [] = Maybe ([b], [c], [b])
forall a. Maybe a
Nothing
stripInfixBy a -> b -> Maybe c
eq [a]
needle (b
x:[b]
xs) = (\([b]
a,[c]
b,[b]
c) -> (b
xb -> [b] -> [b]
forall a. a -> [a] -> [a]
:[b]
a,[c]
b,[b]
c)) (([b], [c], [b]) -> ([b], [c], [b]))
-> Maybe ([b], [c], [b]) -> Maybe ([b], [c], [b])
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> (a -> b -> Maybe c) -> [a] -> [b] -> Maybe ([b], [c], [b])
forall a b c.
(a -> b -> Maybe c) -> [a] -> [b] -> Maybe ([b], [c], [b])
stripInfixBy a -> b -> Maybe c
eq [a]
needle [b]
xs