{-# LANGUAGE DeriveFunctor, DeriveFoldable #-}
module System.FilePattern.Wildcard(
Wildcard(..),
wildcardMatch,
wildcardSubst,
wildcardArity,
equals
) where
import Data.Functor
import Data.List.Extra
import Control.Applicative
import Control.Monad.Extra
import System.FilePattern.ListBy
import Data.Traversable
import qualified Data.Foldable as F
import Prelude
equals :: Eq a => a -> a -> Maybe ()
equals x y = if x == y then Just () else Nothing
data Wildcard a = Wildcard a [a] a
| Literal a
deriving (Show,Eq,Ord,Functor,F.Foldable)
wildcardMatch :: (a -> b -> Maybe c) -> Wildcard [a] -> [b] -> Maybe [Either [c] [b]]
wildcardMatch eq (Literal mid) x = (:[]) . Left <$> eqListBy eq mid x
wildcardMatch eq (Wildcard pre mid post) x = do
(pre, x) <- stripPrefixBy eq pre x
(x, post) <- stripSuffixBy eq post x
mid <- stripInfixes mid x
return $ [Left pre] ++ mid ++ [Left post]
where
stripInfixes [] x = Just [Right x]
stripInfixes (m:ms) y = do
(a,b,x) <- stripInfixBy eq m y
(\c -> Right a:Left b:c) <$> stripInfixes ms x
wildcardSubst :: Applicative m => m b -> (a -> m b) -> Wildcard a -> m [b]
wildcardSubst gap lit (Literal x) = (:[]) <$> lit x
wildcardSubst gap lit (Wildcard pre mid post) = (:) <$>
lit pre <*>
(concat <$> traverse (\v -> (\a b -> [a,b]) <$> gap <*> lit v) (mid ++ [post]))
wildcardArity :: Wildcard a -> Int
wildcardArity (Literal _) = 0
wildcardArity (Wildcard _ xs _) = length xs + 1