module Data.Label
(
Label(..)
,Final(..)
,isError
,terminal
,SetLabel(..)
,LabelSS(..)
) where
import Control.Applicative
import Control.Monad
import qualified Data.Foldable as F
import Data.Monoid
import qualified Data.Set as Set
data Label a =
Q a
| QE deriving(Show, Eq)
instance Functor Label where
fmap _ QE = QE
fmap f (Q q) = Q $ f q
instance Applicative Label where
pure = Q
QE <*> _ = QE
(Q f) <*> q = fmap f q
instance Monad Label where
return = pure
QE >>= _ = QE
(Q q) >>= f = f q
instance (Enum a) => Enum (Label a) where
toEnum = return . toEnum
fromEnum (Q x) = fromEnum x
fromEnum QE = maxBound
instance (Bounded a) => Bounded (Label a) where
minBound = Q minBound
maxBound = QE
instance (Ord a) => Ord (Label a) where
compare QE QE = EQ
compare _ QE = LT
compare QE _ = GT
compare (Q a) (Q b) = compare a b
instance Monoid a => Monoid (Label a) where
mempty = QE
QE `mappend` m = m
m `mappend` QE = m
(Q a) `mappend` (Q b) = Q (a `mappend` b)
instance F.Foldable Label where
foldr _ z QE = z
foldr f z (Q x) = f x z
foldl _ z QE = z
foldl f z (Q x) = f z x
type Final a = Set.Set (Label a)
terminal :: (Ord a) => Final a -> Label a -> Bool
terminal qs q = Set.member q qs
isError::(Eq a) => Label a -> Bool
isError = (QE==)
type SetLabel a = Set.Set (Label a)
type LabelSS a = Label (SetLabel a)