-- | 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 :: forall a b c. (a -> b -> Maybe c) -> [a] -> [b] -> Maybe [c]
eqListBy a -> b -> Maybe c
_ [] [] = forall a. a -> Maybe a
Just []
eqListBy a -> b -> Maybe c
eq (a
a:[a]
as) (b
b:[b]
bs) = 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) (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]
_ = forall a. Maybe a
Nothing


stripPrefixBy :: (a -> b -> Maybe c) -> [a] -> [b] -> Maybe ([c], [b])
stripPrefixBy :: forall a b c. (a -> b -> Maybe c) -> [a] -> [b] -> Maybe ([c], [b])
stripPrefixBy a -> b -> Maybe c
eq [] [b]
bs = forall a. a -> Maybe a
Just ([], [b]
bs)
stripPrefixBy a -> b -> Maybe c
eq [a]
_  [] = 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; forall a a' b. (a -> a') -> (a, b) -> (a', b)
first (c
cforall a. a -> [a] -> [a]
:) forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f 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 :: forall a b c. (a -> b -> Maybe c) -> [a] -> [b] -> Maybe ([b], [c])
stripSuffixBy a -> b -> Maybe c
eq [] [b]
bs = forall a. a -> Maybe a
Just ([b]
bs, []) -- shortcut, but equal to the equation below
stripSuffixBy a -> b -> Maybe c
eq [a]
_  [] = 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) -> (forall a. [a] -> [a]
reverse [b]
b, forall a. [a] -> [a]
reverse [c]
c)) forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> forall a b c. (a -> b -> Maybe c) -> [a] -> [b] -> Maybe ([c], [b])
stripPrefixBy a -> b -> Maybe c
eq (forall a. [a] -> [a]
reverse [a]
as) (forall a. [a] -> [a]
reverse [b]
bs)

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