{-# LANGUAGE DeriveDataTypeable #-}
{-# LANGUAGE DeriveGeneric #-}
{-# LANGUAGE Safe #-}
module Data.Char.Brackets
(
bracketMaps,
brackets,
openBrackets,
closeBrackets,
toOpen,
toClose,
BracketType (Open, Close),
isBracket,
bracketType,
bracketType',
isOpenBracket,
isCloseBracket,
getOppositeChar,
getOppositeChar',
)
where
import Control.Applicative ((<|>))
import Control.DeepSeq (NFData)
import Data.Data (Data)
import Data.Hashable (Hashable)
import Data.Map (Map, fromList, lookup, member)
import Data.Maybe (fromMaybe)
import Data.Tuple (swap)
import GHC.Generics (Generic)
import Test.QuickCheck.Arbitrary (Arbitrary (arbitrary), arbitraryBoundedEnum)
import Prelude hiding (lookup)
data BracketType
=
Open
|
Close
deriving (BracketType
forall a. a -> a -> Bounded a
maxBound :: BracketType
$cmaxBound :: BracketType
minBound :: BracketType
$cminBound :: BracketType
Bounded, Typeable BracketType
BracketType -> DataType
BracketType -> Constr
(forall b. Data b => b -> b) -> BracketType -> BracketType
forall a.
Typeable a
-> (forall (c :: * -> *).
(forall d b. Data d => c (d -> b) -> d -> c b)
-> (forall g. g -> c g) -> a -> c a)
-> (forall (c :: * -> *).
(forall b r. Data b => c (b -> r) -> c r)
-> (forall r. r -> c r) -> Constr -> c a)
-> (a -> Constr)
-> (a -> DataType)
-> (forall (t :: * -> *) (c :: * -> *).
Typeable t =>
(forall d. Data d => c (t d)) -> Maybe (c a))
-> (forall (t :: * -> * -> *) (c :: * -> *).
Typeable t =>
(forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c a))
-> ((forall b. Data b => b -> b) -> a -> a)
-> (forall r r'.
(r -> r' -> r) -> r -> (forall d. Data d => d -> r') -> a -> r)
-> (forall r r'.
(r' -> r -> r) -> r -> (forall d. Data d => d -> r') -> a -> r)
-> (forall u. (forall d. Data d => d -> u) -> a -> [u])
-> (forall u. Int -> (forall d. Data d => d -> u) -> a -> u)
-> (forall (m :: * -> *).
Monad m =>
(forall d. Data d => d -> m d) -> a -> m a)
-> (forall (m :: * -> *).
MonadPlus m =>
(forall d. Data d => d -> m d) -> a -> m a)
-> (forall (m :: * -> *).
MonadPlus m =>
(forall d. Data d => d -> m d) -> a -> m a)
-> Data a
forall u. Int -> (forall d. Data d => d -> u) -> BracketType -> u
forall u. (forall d. Data d => d -> u) -> BracketType -> [u]
forall r r'.
(r -> r' -> r)
-> r -> (forall d. Data d => d -> r') -> BracketType -> r
forall r r'.
(r' -> r -> r)
-> r -> (forall d. Data d => d -> r') -> BracketType -> r
forall (m :: * -> *).
Monad m =>
(forall d. Data d => d -> m d) -> BracketType -> m BracketType
forall (m :: * -> *).
MonadPlus m =>
(forall d. Data d => d -> m d) -> BracketType -> m BracketType
forall (c :: * -> *).
(forall b r. Data b => c (b -> r) -> c r)
-> (forall r. r -> c r) -> Constr -> c BracketType
forall (c :: * -> *).
(forall d b. Data d => c (d -> b) -> d -> c b)
-> (forall g. g -> c g) -> BracketType -> c BracketType
forall (t :: * -> *) (c :: * -> *).
Typeable t =>
(forall d. Data d => c (t d)) -> Maybe (c BracketType)
forall (t :: * -> * -> *) (c :: * -> *).
Typeable t =>
(forall d e. (Data d, Data e) => c (t d e))
-> Maybe (c BracketType)
gmapMo :: forall (m :: * -> *).
MonadPlus m =>
(forall d. Data d => d -> m d) -> BracketType -> m BracketType
$cgmapMo :: forall (m :: * -> *).
MonadPlus m =>
(forall d. Data d => d -> m d) -> BracketType -> m BracketType
gmapMp :: forall (m :: * -> *).
MonadPlus m =>
(forall d. Data d => d -> m d) -> BracketType -> m BracketType
$cgmapMp :: forall (m :: * -> *).
MonadPlus m =>
(forall d. Data d => d -> m d) -> BracketType -> m BracketType
gmapM :: forall (m :: * -> *).
Monad m =>
(forall d. Data d => d -> m d) -> BracketType -> m BracketType
$cgmapM :: forall (m :: * -> *).
Monad m =>
(forall d. Data d => d -> m d) -> BracketType -> m BracketType
gmapQi :: forall u. Int -> (forall d. Data d => d -> u) -> BracketType -> u
$cgmapQi :: forall u. Int -> (forall d. Data d => d -> u) -> BracketType -> u
gmapQ :: forall u. (forall d. Data d => d -> u) -> BracketType -> [u]
$cgmapQ :: forall u. (forall d. Data d => d -> u) -> BracketType -> [u]
gmapQr :: forall r r'.
(r' -> r -> r)
-> r -> (forall d. Data d => d -> r') -> BracketType -> r
$cgmapQr :: forall r r'.
(r' -> r -> r)
-> r -> (forall d. Data d => d -> r') -> BracketType -> r
gmapQl :: forall r r'.
(r -> r' -> r)
-> r -> (forall d. Data d => d -> r') -> BracketType -> r
$cgmapQl :: forall r r'.
(r -> r' -> r)
-> r -> (forall d. Data d => d -> r') -> BracketType -> r
gmapT :: (forall b. Data b => b -> b) -> BracketType -> BracketType
$cgmapT :: (forall b. Data b => b -> b) -> BracketType -> BracketType
dataCast2 :: forall (t :: * -> * -> *) (c :: * -> *).
Typeable t =>
(forall d e. (Data d, Data e) => c (t d e))
-> Maybe (c BracketType)
$cdataCast2 :: forall (t :: * -> * -> *) (c :: * -> *).
Typeable t =>
(forall d e. (Data d, Data e) => c (t d e))
-> Maybe (c BracketType)
dataCast1 :: forall (t :: * -> *) (c :: * -> *).
Typeable t =>
(forall d. Data d => c (t d)) -> Maybe (c BracketType)
$cdataCast1 :: forall (t :: * -> *) (c :: * -> *).
Typeable t =>
(forall d. Data d => c (t d)) -> Maybe (c BracketType)
dataTypeOf :: BracketType -> DataType
$cdataTypeOf :: BracketType -> DataType
toConstr :: BracketType -> Constr
$ctoConstr :: BracketType -> Constr
gunfold :: forall (c :: * -> *).
(forall b r. Data b => c (b -> r) -> c r)
-> (forall r. r -> c r) -> Constr -> c BracketType
$cgunfold :: forall (c :: * -> *).
(forall b r. Data b => c (b -> r) -> c r)
-> (forall r. r -> c r) -> Constr -> c BracketType
gfoldl :: forall (c :: * -> *).
(forall d b. Data d => c (d -> b) -> d -> c b)
-> (forall g. g -> c g) -> BracketType -> c BracketType
$cgfoldl :: forall (c :: * -> *).
(forall d b. Data d => c (d -> b) -> d -> c b)
-> (forall g. g -> c g) -> BracketType -> c BracketType
Data, Int -> BracketType
BracketType -> Int
BracketType -> [BracketType]
BracketType -> BracketType
BracketType -> BracketType -> [BracketType]
BracketType -> BracketType -> BracketType -> [BracketType]
forall a.
(a -> a)
-> (a -> a)
-> (Int -> a)
-> (a -> Int)
-> (a -> [a])
-> (a -> a -> [a])
-> (a -> a -> [a])
-> (a -> a -> a -> [a])
-> Enum a
enumFromThenTo :: BracketType -> BracketType -> BracketType -> [BracketType]
$cenumFromThenTo :: BracketType -> BracketType -> BracketType -> [BracketType]
enumFromTo :: BracketType -> BracketType -> [BracketType]
$cenumFromTo :: BracketType -> BracketType -> [BracketType]
enumFromThen :: BracketType -> BracketType -> [BracketType]
$cenumFromThen :: BracketType -> BracketType -> [BracketType]
enumFrom :: BracketType -> [BracketType]
$cenumFrom :: BracketType -> [BracketType]
fromEnum :: BracketType -> Int
$cfromEnum :: BracketType -> Int
toEnum :: Int -> BracketType
$ctoEnum :: Int -> BracketType
pred :: BracketType -> BracketType
$cpred :: BracketType -> BracketType
succ :: BracketType -> BracketType
$csucc :: BracketType -> BracketType
Enum, BracketType -> BracketType -> Bool
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: BracketType -> BracketType -> Bool
$c/= :: BracketType -> BracketType -> Bool
== :: BracketType -> BracketType -> Bool
$c== :: BracketType -> BracketType -> Bool
Eq, forall x. Rep BracketType x -> BracketType
forall x. BracketType -> Rep BracketType x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
$cto :: forall x. Rep BracketType x -> BracketType
$cfrom :: forall x. BracketType -> Rep BracketType x
Generic, Eq BracketType
BracketType -> BracketType -> Bool
BracketType -> BracketType -> Ordering
BracketType -> BracketType -> BracketType
forall a.
Eq a
-> (a -> a -> Ordering)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> a)
-> (a -> a -> a)
-> Ord a
min :: BracketType -> BracketType -> BracketType
$cmin :: BracketType -> BracketType -> BracketType
max :: BracketType -> BracketType -> BracketType
$cmax :: BracketType -> BracketType -> BracketType
>= :: BracketType -> BracketType -> Bool
$c>= :: BracketType -> BracketType -> Bool
> :: BracketType -> BracketType -> Bool
$c> :: BracketType -> BracketType -> Bool
<= :: BracketType -> BracketType -> Bool
$c<= :: BracketType -> BracketType -> Bool
< :: BracketType -> BracketType -> Bool
$c< :: BracketType -> BracketType -> Bool
compare :: BracketType -> BracketType -> Ordering
$ccompare :: BracketType -> BracketType -> Ordering
Ord, ReadPrec [BracketType]
ReadPrec BracketType
Int -> ReadS BracketType
ReadS [BracketType]
forall a.
(Int -> ReadS a)
-> ReadS [a] -> ReadPrec a -> ReadPrec [a] -> Read a
readListPrec :: ReadPrec [BracketType]
$creadListPrec :: ReadPrec [BracketType]
readPrec :: ReadPrec BracketType
$creadPrec :: ReadPrec BracketType
readList :: ReadS [BracketType]
$creadList :: ReadS [BracketType]
readsPrec :: Int -> ReadS BracketType
$creadsPrec :: Int -> ReadS BracketType
Read, Int -> BracketType -> ShowS
[BracketType] -> ShowS
BracketType -> String
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [BracketType] -> ShowS
$cshowList :: [BracketType] -> ShowS
show :: BracketType -> String
$cshow :: BracketType -> String
showsPrec :: Int -> BracketType -> ShowS
$cshowsPrec :: Int -> BracketType -> ShowS
Show)
instance Arbitrary BracketType where
arbitrary :: Gen BracketType
arbitrary = forall a. (Bounded a, Enum a) => Gen a
arbitraryBoundedEnum
instance Hashable BracketType
instance NFData BracketType
bracketMaps :: [(Char, Char)]
bracketMaps :: [(Char, Char)]
bracketMaps =
[ (Char
'(', Char
')'),
(Char
'[', Char
']'),
(Char
'{', Char
'}'),
(Char
'\x0f3a', Char
'\x0f3b'),
(Char
'\x0f3c', Char
'\x0f3d'),
(Char
'\x169b', Char
'\x169c'),
(Char
'\x2045', Char
'\x2046'),
(Char
'\x207d', Char
'\x207e'),
(Char
'\x208d', Char
'\x208e'),
(Char
'\x2308', Char
'\x2309'),
(Char
'\x230a', Char
'\x230b'),
(Char
'\x2329', Char
'\x232a'),
(Char
'\x2768', Char
'\x2769'),
(Char
'\x276a', Char
'\x276b'),
(Char
'\x276c', Char
'\x276d'),
(Char
'\x276e', Char
'\x276f'),
(Char
'\x2770', Char
'\x2771'),
(Char
'\x2772', Char
'\x2773'),
(Char
'\x2774', Char
'\x2775'),
(Char
'\x27c5', Char
'\x27c6'),
(Char
'\x27e6', Char
'\x27e7'),
(Char
'\x27e8', Char
'\x27e9'),
(Char
'\x27ea', Char
'\x27eb'),
(Char
'\x27ec', Char
'\x27ed'),
(Char
'\x27ee', Char
'\x27ef'),
(Char
'\x2983', Char
'\x2984'),
(Char
'\x2985', Char
'\x2986'),
(Char
'\x2987', Char
'\x2988'),
(Char
'\x2989', Char
'\x298a'),
(Char
'\x298b', Char
'\x298c'),
(Char
'\x298d', Char
'\x2990'),
(Char
'\x298f', Char
'\x298e'),
(Char
'\x2991', Char
'\x2992'),
(Char
'\x2993', Char
'\x2994'),
(Char
'\x2995', Char
'\x2996'),
(Char
'\x2997', Char
'\x2998'),
(Char
'\x29d8', Char
'\x29d9'),
(Char
'\x29da', Char
'\x29db'),
(Char
'\x29fc', Char
'\x29fd'),
(Char
'\x2e22', Char
'\x2e23'),
(Char
'\x2e24', Char
'\x2e25'),
(Char
'\x2e26', Char
'\x2e27'),
(Char
'\x2e28', Char
'\x2e29'),
(Char
'\x3008', Char
'\x3009'),
(Char
'\x300a', Char
'\x300b'),
(Char
'\x300c', Char
'\x300d'),
(Char
'\x300e', Char
'\x300f'),
(Char
'\x3010', Char
'\x3011'),
(Char
'\x3014', Char
'\x3015'),
(Char
'\x3016', Char
'\x3017'),
(Char
'\x3018', Char
'\x3019'),
(Char
'\x301a', Char
'\x301b'),
(Char
'\xfe59', Char
'\xfe5a'),
(Char
'\xfe5b', Char
'\xfe5c'),
(Char
'\xfe5d', Char
'\xfe5e'),
(Char
'\xff08', Char
'\xff09'),
(Char
'\xff3b', Char
'\xff3d'),
(Char
'\xff5b', Char
'\xff5d'),
(Char
'\xff5f', Char
'\xff60'),
(Char
'\xff62', Char
'\xff63')
]
brackets ::
[Char]
brackets :: String
brackets = [Char
ci | ~(Char
ca, Char
cb) <- [(Char, Char)]
bracketMaps, Char
ci <- [Char
ca, Char
cb]]
openBrackets ::
[Char]
openBrackets :: String
openBrackets = forall a b. (a -> b) -> [a] -> [b]
map forall a b. (a, b) -> a
fst [(Char, Char)]
bracketMaps
closeBrackets ::
[Char]
closeBrackets :: String
closeBrackets = forall a b. (a -> b) -> [a] -> [b]
map forall a b. (a, b) -> b
snd [(Char, Char)]
bracketMaps
toClose :: Map Char Char
toClose :: Map Char Char
toClose = forall k a. Ord k => [(k, a)] -> Map k a
fromList [(Char, Char)]
bracketMaps
toOpen :: Map Char Char
toOpen :: Map Char Char
toOpen = forall k a. Ord k => [(k, a)] -> Map k a
fromList (forall a b. (a -> b) -> [a] -> [b]
map forall a b. (a, b) -> (b, a)
swap [(Char, Char)]
bracketMaps)
isBracket ::
Char ->
Bool
isBracket :: Char -> Bool
isBracket Char
c = forall {a}. Map Char a -> Bool
go Map Char Char
toClose Bool -> Bool -> Bool
|| forall {a}. Map Char a -> Bool
go Map Char Char
toOpen
where
go :: Map Char a -> Bool
go = forall k a. Ord k => k -> Map k a -> Bool
member Char
c
isOpenBracket ::
Char ->
Bool
isOpenBracket :: Char -> Bool
isOpenBracket = (forall k a. Ord k => k -> Map k a -> Bool
`member` Map Char Char
toClose)
isCloseBracket ::
Char ->
Bool
isCloseBracket :: Char -> Bool
isCloseBracket = (forall k a. Ord k => k -> Map k a -> Bool
`member` Map Char Char
toOpen)
bracketType :: Char -> Maybe BracketType
bracketType :: Char -> Maybe BracketType
bracketType Char
c
| forall {a}. Map Char a -> Bool
go Map Char Char
toClose = forall a. a -> Maybe a
Just BracketType
Open
| forall {a}. Map Char a -> Bool
go Map Char Char
toOpen = forall a. a -> Maybe a
Just BracketType
Close
| Bool
otherwise = forall a. Maybe a
Nothing
where
go :: Map Char a -> Bool
go = forall k a. Ord k => k -> Map k a -> Bool
member Char
c
bracketType' :: Char -> BracketType
bracketType' :: Char -> BracketType
bracketType' Char
c
| forall k a. Ord k => k -> Map k a -> Bool
member Char
c Map Char Char
toClose = BracketType
Open
| Bool
otherwise = BracketType
Close
getOppositeChar ::
Char ->
Maybe Char
getOppositeChar :: Char -> Maybe Char
getOppositeChar Char
c = forall {a}. Map Char a -> Maybe a
go Map Char Char
toClose forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> forall {a}. Map Char a -> Maybe a
go Map Char Char
toOpen
where
go :: Map Char a -> Maybe a
go = forall k a. Ord k => k -> Map k a -> Maybe a
lookup Char
c
getOppositeChar' ::
Char ->
Char
getOppositeChar' :: Char -> Char
getOppositeChar' = forall a. a -> Maybe a -> a
fromMaybe forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Char -> Maybe Char
getOppositeChar