Created
April 15, 2016 12:46
-
-
Save rodrigogribeiro/9be413e5b59d87812f3c8eaae2dc2dcc to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
{-# LANGUAGE DataKinds, KindSignatures, GADTs, TypeFamilies, TemplateHaskell, QuasiQuotes, ScopedTypeVariables, PolyKinds, FlexibleContexts, UndecidableInstances, TypeOperators #-} | |
module Regex where | |
import Data.Proxy | |
import Data.Singletons.Prelude | |
import Data.Singletons.TH | |
import Data.Singletons.TypeLits | |
data Falsum | |
exFalsum :: Falsum -> a | |
exFalsum _ = undefined | |
type family (++) (as :: [k]) (bs :: [k]) :: [k] where | |
(++) a '[] = a | |
(++) '[] b = b | |
(++) (a ': as) bs = a ': (as ++ bs) | |
$(singletons [d| | |
data RegExp a = Sym a | |
| Eps | |
| Cat (RegExp a) (RegExp a) | |
| Choice (RegExp a) (RegExp a) | |
| Star (RegExp a) |]) | |
data InRegExp (n :: [Nat]) (e :: RegExp [Nat]) where | |
InEps :: InRegExp '[] Eps | |
InSym :: KnownNat n => proxy n -> InRegExp (n ': '[]) (Sym (n ': '[])) | |
InCat :: InRegExp xs l -> InRegExp ys r -> | |
(zs :~: xs ++ ys) -> InRegExp zs (Cat l r) | |
InChoiceL :: InRegExp ns l -> InRegExp ns (Choice l r) | |
InChoiceR :: InRegExp ns r -> InRegExp ns (Choice l r) | |
InStarBase :: InRegExp '[] (Star l) | |
InStarRec :: InRegExp ns l -> InRegExp ns' (Star l) -> InRegExp (ns ++ ns') (Star l) | |
symNotEmpty :: InRegExp '[] (Sym ns) -> Falsum | |
symNotEmpty _ = undefined | |
inCatInv :: InRegExp (xs ++ ys) (Cat e e') -> (InRegExp xs e , InRegExp ys e') | |
inCatInv (InCat p p' Refl) = (p , p') | |
inChoiceInv :: InRegExp zs (Choice e e') -> Either (InRegExp zs e) (InRegExp zs e') | |
inChoiceInv (InChoiceL p) = Left p | |
inChoiceInv (InChoiceR p) = Right p | |
hasEmpty :: SRegExp e -> Either (InRegExp '[] e) (InRegExp '[] e -> Falsum) | |
hasEmpty SEps = Left InEps | |
hasEmpty (SSym _) = exFalsum (symNotEmpty undefined) | |
hasEmpty (SCat e e') = case hasEmpty e of | |
Left pr -> case hasEmpty e' of | |
Left pr' -> Left (InCat pr pr') | |
Right err' -> Right (err' . snd . inCatInv) | |
Right err -> Right (err . fst . inCatInv) | |
hasEmpty (SChoice e e') = case hasEmpty e of | |
Left pr -> Left (InChoiceL pr) | |
Right err -> case hasEmpty e' of | |
Left pr' -> Left (InChoiceR pr') | |
Right err' -> Right (either err err' . inChoiceInv) | |
hasEmpty (SStar e) = Left InStarBase |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment