{-# LANGUAGE DeriveDataTypeable, DeriveGeneric, Safe #-}
module Data.Char.Brackets (
bracketMaps, brackets, openBrackets, closeBrackets, toOpen, toClose
, BracketType(Open, Close), isBracket, bracketType, bracketType', isOpenBracket, isCloseBracket
, getOppositeChar, getOppositeChar'
) where
import Prelude hiding (lookup)
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)
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