    -- | 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
    _ [] [] = [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 a b c. (a -> b -> c) -> Maybe a -> Maybe b -> 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 :: forall a b c. (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 <- a -> b -> Maybe c
    eq a
    a b
    b; first (c:) <$> stripPrefixBy eq as 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 = ([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 :: 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) <- (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