----------------------------------------------------------------------------- -- | -- Module : Text.Regex.Impl -- Copyright : (c) Chris Kuklewicz 2006 -- SPDX-License-Identifier: BSD-3-Clause -- -- Maintainer : hvr@gnu.org -- Stability : experimental -- Portability : non-portable (Text.Regex.Base needs MPTC+FD) -- -- Helper functions for defining certain instances of -- 'RegexContext'. These help when defining instances of 'RegexContext' -- with repeated types: -- -- @ -- instance (RegexLike regex source) => RegexContext regex source source where -- @ -- -- runs into overlapping restrictions. To avoid this I have each backend -- define, for its own @Regex@ type: -- -- @ -- instance RegexContext Regex String String where -- match = polymatch -- matchM = polymatchM -- @ -- -- @ -- instance RegexContext Regex ByteString ByteString where -- match = polymatch -- matchM = polymatchM -- @ -- -- @ -- instance RegexContext Regex Text Text where -- match = polymatch -- matchM = polymatchM -- @ ------------------------------------------------------------------------------- module Text.Regex.Base.Impl(polymatch,polymatchM) where import Prelude hiding (fail) import Control.Monad.Fail (MonadFail(fail)) import Text.Regex.Base import Data.Array((!)) regexFailed :: (MonadFail m) => m b {-# INLINE regexFailed #-} regexFailed = fail $ "regex failed to match" actOn :: (RegexLike r s,MonadFail m) => ((s,MatchText s,s)->t) -> r -> s -> m t {-# INLINE actOn #-} actOn f r s = case matchOnceText r s of Nothing -> regexFailed Just preMApost -> return (f preMApost) polymatch :: (RegexLike a b) => a -> b -> b {-# INLINE polymatch #-} polymatch r s = case matchOnceText r s of Nothing -> empty Just (_, ma, _) -> fst (ma ! 0) polymatchM :: (RegexLike a b,MonadFail m) => a -> b -> m b {-# INLINE polymatchM #-} polymatchM = actOn (\ (_, ma, _) -> fst (ma ! 0))