    {-# Language StandaloneDeriving, DeriveDataTypeable, FlexibleContexts, UndecidableInstances, FlexibleInstances #-}
    module Language.Javascript.JMacro.Types (
      JType(..), Constraint(..), JLocalType, VarRef, anyType, parseType, runTypeParser
      ) where

    import Control.Applicative hiding ((<|>))
    import Data.Char

    import Data.Maybe(fromMaybe)

    import Text.ParserCombinators.Parsec
    import Text.Parsec.Prim hiding (runParser, try)
    import Text.ParserCombinators.Parsec.Language(emptyDef)
    import qualified Text.ParserCombinators.Parsec.Token as P

    import qualified Data.Map as M
    import Data.Map (Map)
    import Data.Set (Set)
    import Data.Generics

    type VarRef = (Maybe String, Int)

    -- sum types for list/record, map/record

    data JType = JTNum
               | JTString
               | JTBool
               | JTStat
               | JTFunc [JType] (JType)
               | JTList JType
               | JTMap  JType
               | JTRecord JType (Map String JType)
               | JTRigid VarRef (Set Constraint)
               | JTImpossible
               | JTFree VarRef
               | JTForall [VarRef] JType
                 deriving (JType -> JType -> Bool
    (JType -> JType -> Bool) -> (JType -> JType -> Bool) -> Eq JType
    forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
    $c== :: JType -> JType -> Bool
    == :: JType -> JType -> Bool
    $c/= :: JType -> JType -> Bool
    /= :: JType -> JType -> Bool
    Eq, Eq JType
    Eq JType =>
    (JType -> JType -> Ordering)
    -> (JType -> JType -> Bool)
    -> (JType -> JType -> Bool)
    -> (JType -> JType -> Bool)
    -> (JType -> JType -> Bool)
    -> (JType -> JType -> JType)
    -> (JType -> JType -> JType)
    -> Ord JType
    JType -> JType -> Bool
    JType -> JType -> Ordering
    JType -> JType -> JType
    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
    $ccompare :: JType -> JType -> Ordering
    compare :: JType -> JType -> Ordering
    $c< :: JType -> JType -> Bool
    < :: JType -> JType -> Bool
    $c<= :: JType -> JType -> Bool
    <= :: JType -> JType -> Bool
    $c> :: JType -> JType -> Bool
    > :: JType -> JType -> Bool
    $c>= :: JType -> JType -> Bool
    >= :: JType -> JType -> Bool
    $cmax :: JType -> JType -> JType
    max :: JType -> JType -> JType
    $cmin :: JType -> JType -> JType
    min :: JType -> JType -> JType
    Ord, ReadPrec [JType]
    ReadPrec JType
    Int -> ReadS JType
    ReadS [JType]
    (Int -> ReadS JType)
    -> ReadS [JType]
    -> ReadPrec JType
    -> ReadPrec [JType]
    -> Read JType
    forall a.
    (Int -> ReadS a)
    -> ReadS [a] -> ReadPrec a -> ReadPrec [a] -> Read a
    $creadsPrec :: Int -> ReadS JType
    readsPrec :: Int -> ReadS JType
    $creadList :: ReadS [JType]
    readList :: ReadS [JType]
    $creadPrec :: ReadPrec JType
    readPrec :: ReadPrec JType
    $creadListPrec :: ReadPrec [JType]
    readListPrec :: ReadPrec [JType]
    Read, Int -> JType -> ShowS
    [JType] -> ShowS
    JType -> [Char]
    (Int -> JType -> ShowS)
    -> (JType -> [Char]) -> ([JType] -> ShowS) -> Show JType
    forall a.
    (Int -> a -> ShowS) -> (a -> [Char]) -> ([a] -> ShowS) -> Show a
    $cshowsPrec :: Int -> JType -> ShowS
    showsPrec :: Int -> JType -> ShowS
    $cshow :: JType -> [Char]
    show :: JType -> [Char]
    $cshowList :: [JType] -> ShowS
    showList :: [JType] -> ShowS
    Show, Typeable, Typeable JType
    Typeable JType =>
    (forall (c :: * -> *).
     (forall d b. Data d => c (d -> b) -> d -> c b)
     -> (forall g. g -> c g) -> JType -> c JType)
    -> (forall (c :: * -> *).
        (forall b r. Data b => c (b -> r) -> c r)
        -> (forall r. r -> c r) -> Constr -> c JType)
    -> (JType -> Constr)
    -> (JType -> DataType)
    -> (forall (t :: * -> *) (c :: * -> *).
        Typeable t =>
        (forall d. Data d => c (t d)) -> Maybe (c JType))
    -> (forall (t :: * -> * -> *) (c :: * -> *).
        Typeable t =>
        (forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c JType))
    -> ((forall b. Data b => b -> b) -> JType -> JType)
    -> (forall r r'.
        (r -> r' -> r) -> r -> (forall d. Data d => d -> r') -> JType -> r)
    -> (forall r r'.
        (r' -> r -> r) -> r -> (forall d. Data d => d -> r') -> JType -> r)
    -> (forall u. (forall d. Data d => d -> u) -> JType -> [u])
    -> (forall u. Int -> (forall d. Data d => d -> u) -> JType -> u)
    -> (forall (m :: * -> *).
        Monad m =>
        (forall d. Data d => d -> m d) -> JType -> m JType)
    -> (forall (m :: * -> *).
        MonadPlus m =>
        (forall d. Data d => d -> m d) -> JType -> m JType)
    -> (forall (m :: * -> *).
        MonadPlus m =>
        (forall d. Data d => d -> m d) -> JType -> m JType)
    -> Data JType
    JType -> Constr
    JType -> DataType
    (forall b. Data b => b -> b) -> JType -> JType
    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) -> JType -> u
    forall u. (forall d. Data d => d -> u) -> JType -> [u]
    forall r r'.
    (r -> r' -> r) -> r -> (forall d. Data d => d -> r') -> JType -> r
    forall r r'.
    (r' -> r -> r) -> r -> (forall d. Data d => d -> r') -> JType -> r
    forall (m :: * -> *).
    Monad m =>
    (forall d. Data d => d -> m d) -> JType -> m JType
    forall (m :: * -> *).
    MonadPlus m =>
    (forall d. Data d => d -> m d) -> JType -> m JType
    forall (c :: * -> *).
    (forall b r. Data b => c (b -> r) -> c r)
    -> (forall r. r -> c r) -> Constr -> c JType
    forall (c :: * -> *).
    (forall d b. Data d => c (d -> b) -> d -> c b)
    -> (forall g. g -> c g) -> JType -> c JType
    forall (t :: * -> *) (c :: * -> *).
    Typeable t =>
    (forall d. Data d => c (t d)) -> Maybe (c JType)
    forall (t :: * -> * -> *) (c :: * -> *).
    Typeable t =>
    (forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c JType)
    $cgfoldl :: forall (c :: * -> *).
    (forall d b. Data d => c (d -> b) -> d -> c b)
    -> (forall g. g -> c g) -> JType -> c JType
    gfoldl :: forall (c :: * -> *).
    (forall d b. Data d => c (d -> b) -> d -> c b)
    -> (forall g. g -> c g) -> JType -> c JType
    $cgunfold :: forall (c :: * -> *).
    (forall b r. Data b => c (b -> r) -> c r)
    -> (forall r. r -> c r) -> Constr -> c JType
    gunfold :: forall (c :: * -> *).
    (forall b r. Data b => c (b -> r) -> c r)
    -> (forall r. r -> c r) -> Constr -> c JType
    $ctoConstr :: JType -> Constr
    toConstr :: JType -> Constr
    $cdataTypeOf :: JType -> DataType
    dataTypeOf :: JType -> DataType
    $cdataCast1 :: forall (t :: * -> *) (c :: * -> *).
    Typeable t =>
    (forall d. Data d => c (t d)) -> Maybe (c JType)
    dataCast1 :: forall (t :: * -> *) (c :: * -> *).
    Typeable t =>
    (forall d. Data d => c (t d)) -> Maybe (c JType)
    $cdataCast2 :: forall (t :: * -> * -> *) (c :: * -> *).
    Typeable t =>
    (forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c JType)
    dataCast2 :: forall (t :: * -> * -> *) (c :: * -> *).
    Typeable t =>
    (forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c JType)
    $cgmapT :: (forall b. Data b => b -> b) -> JType -> JType
    gmapT :: (forall b. Data b => b -> b) -> JType -> JType
    $cgmapQl :: forall r r'.
    (r -> r' -> r) -> r -> (forall d. Data d => d -> r') -> JType -> r
    gmapQl :: forall r r'.
    (r -> r' -> r) -> r -> (forall d. Data d => d -> r') -> JType -> r
    $cgmapQr :: forall r r'.
    (r' -> r -> r) -> r -> (forall d. Data d => d -> r') -> JType -> r
    gmapQr :: forall r r'.
    (r' -> r -> r) -> r -> (forall d. Data d => d -> r') -> JType -> r
    $cgmapQ :: forall u. (forall d. Data d => d -> u) -> JType -> [u]
    gmapQ :: forall u. (forall d. Data d => d -> u) -> JType -> [u]
    $cgmapQi :: forall u. Int -> (forall d. Data d => d -> u) -> JType -> u
    gmapQi :: forall u. Int -> (forall d. Data d => d -> u) -> JType -> u
    $cgmapM :: forall (m :: * -> *).
    Monad m =>
    (forall d. Data d => d -> m d) -> JType -> m JType
    gmapM :: forall (m :: * -> *).
    Monad m =>
    (forall d. Data d => d -> m d) -> JType -> m JType
    $cgmapMp :: forall (m :: * -> *).
    MonadPlus m =>
    (forall d. Data d => d -> m d) -> JType -> m JType
    gmapMp :: forall (m :: * -> *).
    MonadPlus m =>
    (forall d. Data d => d -> m d) -> JType -> m JType
    $cgmapMo :: forall (m :: * -> *).
    MonadPlus m =>
    (forall d. Data d => d -> m d) -> JType -> m JType
    gmapMo :: forall (m :: * -> *).
    MonadPlus m =>
    (forall d. Data d => d -> m d) -> JType -> m JType
    Data)

    data Constraint = Sub JType
                    | Super JType
                      deriving (Constraint -> Constraint -> Bool
    (Constraint -> Constraint -> Bool)
    -> (Constraint -> Constraint -> Bool) -> Eq Constraint
    forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
    $c== :: Constraint -> Constraint -> Bool
    == :: Constraint -> Constraint -> Bool
    $c/= :: Constraint -> Constraint -> Bool
    /= :: Constraint -> Constraint -> Bool
    Eq, Eq Constraint
    Eq Constraint =>
    (Constraint -> Constraint -> Ordering)
    -> (Constraint -> Constraint -> Bool)
    -> (Constraint -> Constraint -> Bool)
    -> (Constraint -> Constraint -> Bool)
    -> (Constraint -> Constraint -> Bool)
    -> (Constraint -> Constraint -> Constraint)
    -> (Constraint -> Constraint -> Constraint)
    -> Ord Constraint
    Constraint -> Constraint -> Bool
    Constraint -> Constraint -> Ordering
    Constraint -> Constraint -> Constraint
    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
    $ccompare :: Constraint -> Constraint -> Ordering
    compare :: Constraint -> Constraint -> Ordering
    $c< :: Constraint -> Constraint -> Bool
    < :: Constraint -> Constraint -> Bool
    $c<= :: Constraint -> Constraint -> Bool
    <= :: Constraint -> Constraint -> Bool
    $c> :: Constraint -> Constraint -> Bool
    > :: Constraint -> Constraint -> Bool
    $c>= :: Constraint -> Constraint -> Bool
    >= :: Constraint -> Constraint -> Bool
    $cmax :: Constraint -> Constraint -> Constraint
    max :: Constraint -> Constraint -> Constraint
    $cmin :: Constraint -> Constraint -> Constraint
    min :: Constraint -> Constraint -> Constraint
    Ord, ReadPrec [Constraint]
    ReadPrec Constraint
    Int -> ReadS Constraint
    ReadS [Constraint]
    (Int -> ReadS Constraint)
    -> ReadS [Constraint]
    -> ReadPrec Constraint
    -> ReadPrec [Constraint]
    -> Read Constraint
    forall a.
    (Int -> ReadS a)
    -> ReadS [a] -> ReadPrec a -> ReadPrec [a] -> Read a
    $creadsPrec :: Int -> ReadS Constraint
    readsPrec :: Int -> ReadS Constraint
    $creadList :: ReadS [Constraint]
    readList :: ReadS [Constraint]
    $creadPrec :: ReadPrec Constraint
    readPrec :: ReadPrec Constraint
    $creadListPrec :: ReadPrec [Constraint]
    readListPrec :: ReadPrec [Constraint]
    Read, Int -> Constraint -> ShowS
    [Constraint] -> ShowS
    Constraint -> [Char]
    (Int -> Constraint -> ShowS)
    -> (Constraint -> [Char])
    -> ([Constraint] -> ShowS)
    -> Show Constraint
    forall a.
    (Int -> a -> ShowS) -> (a -> [Char]) -> ([a] -> ShowS) -> Show a
    $cshowsPrec :: Int -> Constraint -> ShowS
    showsPrec :: Int -> Constraint -> ShowS
    $cshow :: Constraint -> [Char]
    show :: Constraint -> [Char]
    $cshowList :: [Constraint] -> ShowS
    showList :: [Constraint] -> ShowS
    Show, Typeable, Typeable Constraint
    Typeable Constraint =>
    (forall (c :: * -> *).
     (forall d b. Data d => c (d -> b) -> d -> c b)
     -> (forall g. g -> c g) -> Constraint -> c Constraint)
    -> (forall (c :: * -> *).
        (forall b r. Data b => c (b -> r) -> c r)
        -> (forall r. r -> c r) -> Constr -> c Constraint)
    -> (Constraint -> Constr)
    -> (Constraint -> DataType)
    -> (forall (t :: * -> *) (c :: * -> *).
        Typeable t =>
        (forall d. Data d => c (t d)) -> Maybe (c Constraint))
    -> (forall (t :: * -> * -> *) (c :: * -> *).
        Typeable t =>
        (forall d e. (Data d, Data e) => c (t d e))
        -> Maybe (c Constraint))
    -> ((forall b. Data b => b -> b) -> Constraint -> Constraint)
    -> (forall r r'.
        (r -> r' -> r)
        -> r -> (forall d. Data d => d -> r') -> Constraint -> r)
    -> (forall r r'.
        (r' -> r -> r)
        -> r -> (forall d. Data d => d -> r') -> Constraint -> r)
    -> (forall u. (forall d. Data d => d -> u) -> Constraint -> [u])
    -> (forall u.
        Int -> (forall d. Data d => d -> u) -> Constraint -> u)
    -> (forall (m :: * -> *).
        Monad m =>
        (forall d. Data d => d -> m d) -> Constraint -> m Constraint)
    -> (forall (m :: * -> *).
        MonadPlus m =>
        (forall d. Data d => d -> m d) -> Constraint -> m Constraint)
    -> (forall (m :: * -> *).
        MonadPlus m =>
        (forall d. Data d => d -> m d) -> Constraint -> m Constraint)
    -> Data Constraint
    Constraint -> Constr
    Constraint -> DataType
    (forall b. Data b => b -> b) -> Constraint -> Constraint
    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) -> Constraint -> u
    forall u. (forall d. Data d => d -> u) -> Constraint -> [u]
    forall r r'.
    (r -> r' -> r)
    -> r -> (forall d. Data d => d -> r') -> Constraint -> r
    forall r r'.
    (r' -> r -> r)
    -> r -> (forall d. Data d => d -> r') -> Constraint -> r
    forall (m :: * -> *).
    Monad m =>
    (forall d. Data d => d -> m d) -> Constraint -> m Constraint
    forall (m :: * -> *).
    MonadPlus m =>
    (forall d. Data d => d -> m d) -> Constraint -> m Constraint
    forall (c :: * -> *).
    (forall b r. Data b => c (b -> r) -> c r)
    -> (forall r. r -> c r) -> Constr -> c Constraint
    forall (c :: * -> *).
    (forall d b. Data d => c (d -> b) -> d -> c b)
    -> (forall g. g -> c g) -> Constraint -> c Constraint
    forall (t :: * -> *) (c :: * -> *).
    Typeable t =>
    (forall d. Data d => c (t d)) -> Maybe (c Constraint)
    forall (t :: * -> * -> *) (c :: * -> *).
    Typeable t =>
    (forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c Constraint)
    $cgfoldl :: forall (c :: * -> *).
    (forall d b. Data d => c (d -> b) -> d -> c b)
    -> (forall g. g -> c g) -> Constraint -> c Constraint
    gfoldl :: forall (c :: * -> *).
    (forall d b. Data d => c (d -> b) -> d -> c b)
    -> (forall g. g -> c g) -> Constraint -> c Constraint
    $cgunfold :: forall (c :: * -> *).
    (forall b r. Data b => c (b -> r) -> c r)
    -> (forall r. r -> c r) -> Constr -> c Constraint
    gunfold :: forall (c :: * -> *).
    (forall b r. Data b => c (b -> r) -> c r)
    -> (forall r. r -> c r) -> Constr -> c Constraint
    $ctoConstr :: Constraint -> Constr
    toConstr :: Constraint -> Constr
    $cdataTypeOf :: Constraint -> DataType
    dataTypeOf :: Constraint -> DataType
    $cdataCast1 :: forall (t :: * -> *) (c :: * -> *).
    Typeable t =>
    (forall d. Data d => c (t d)) -> Maybe (c Constraint)
    dataCast1 :: forall (t :: * -> *) (c :: * -> *).
    Typeable t =>
    (forall d. Data d => c (t d)) -> Maybe (c Constraint)
    $cdataCast2 :: forall (t :: * -> * -> *) (c :: * -> *).
    Typeable t =>
    (forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c Constraint)
    dataCast2 :: forall (t :: * -> * -> *) (c :: * -> *).
    Typeable t =>
    (forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c Constraint)
    $cgmapT :: (forall b. Data b => b -> b) -> Constraint -> Constraint
    gmapT :: (forall b. Data b => b -> b) -> Constraint -> Constraint
    $cgmapQl :: forall r r'.
    (r -> r' -> r)
    -> r -> (forall d. Data d => d -> r') -> Constraint -> r
    gmapQl :: forall r r'.
    (r -> r' -> r)
    -> r -> (forall d. Data d => d -> r') -> Constraint -> r
    $cgmapQr :: forall r r'.
    (r' -> r -> r)
    -> r -> (forall d. Data d => d -> r') -> Constraint -> r
    gmapQr :: forall r r'.
    (r' -> r -> r)
    -> r -> (forall d. Data d => d -> r') -> Constraint -> r
    $cgmapQ :: forall u. (forall d. Data d => d -> u) -> Constraint -> [u]
    gmapQ :: forall u. (forall d. Data d => d -> u) -> Constraint -> [u]
    $cgmapQi :: forall u. Int -> (forall d. Data d => d -> u) -> Constraint -> u
    gmapQi :: forall u. Int -> (forall d. Data d => d -> u) -> Constraint -> u
    $cgmapM :: forall (m :: * -> *).
    Monad m =>
    (forall d. Data d => d -> m d) -> Constraint -> m Constraint
    gmapM :: forall (m :: * -> *).
    Monad m =>
    (forall d. Data d => d -> m d) -> Constraint -> m Constraint
    $cgmapMp :: forall (m :: * -> *).
    MonadPlus m =>
    (forall d. Data d => d -> m d) -> Constraint -> m Constraint
    gmapMp :: forall (m :: * -> *).
    MonadPlus m =>
    (forall d. Data d => d -> m d) -> Constraint -> m Constraint
    $cgmapMo :: forall (m :: * -> *).
    MonadPlus m =>
    (forall d. Data d => d -> m d) -> Constraint -> m Constraint
    gmapMo :: forall (m :: * -> *).
    MonadPlus m =>
    (forall d. Data d => d -> m d) -> Constraint -> m Constraint
    Data)
    {-
                     | Choice Constraint Constraint
                     | GLB (Set JType)
                     | LUB (Set JType)
    -}
    type JLocalType = ([(VarRef,Constraint)], JType)

    type TypeParserState = (Int, Map String Int)

    type TypeParser a = CharParser TypeParserState a

    typLang :: P.LanguageDef TypeParserState
    typLang :: LanguageDef TypeParserState
    typLang = LanguageDef TypeParserState
    forall st. LanguageDef st
    emptyDef {
               P.reservedNames = ["()","->"],
               P.reservedOpNames = ["()","->","::"],
               P.identLetter = alphaNum <|> oneOf "_$",
               P.identStart  = letter <|> oneOf "_$"
              }

    lexer :: P.TokenParser TypeParserState
    lexer :: TokenParser TypeParserState
    lexer = LanguageDef TypeParserState -> TokenParser TypeParserState
    forall s (m :: * -> *) u.
    Stream s m Char =>
    GenLanguageDef s u m -> GenTokenParser s u m
    P.makeTokenParser LanguageDef TypeParserState
    typLang

    reservedOp :: String -> TypeParser ()
    parens, braces, brackets, lexeme :: TypeParser a -> TypeParser a
    identifier :: TypeParser String
    commaSep, commaSep1 :: TypeParser a -> TypeParser [a]
    parens :: forall a. TypeParser a -> TypeParser a
    parens    = TokenParser TypeParserState
    -> forall a. TypeParser a -> TypeParser a
    forall s u (m :: * -> *).
    GenTokenParser s u m
    -> forall a. ParsecT s u m a -> ParsecT s u m a
    P.parens TokenParser TypeParserState
    lexer
    braces :: forall a. TypeParser a -> TypeParser a
    braces    = TokenParser TypeParserState
    -> forall a. TypeParser a -> TypeParser a
    forall s u (m :: * -> *).
    GenTokenParser s u m
    -> forall a. ParsecT s u m a -> ParsecT s u m a
    P.braces TokenParser TypeParserState
    lexer
    brackets :: forall a. TypeParser a -> TypeParser a
    brackets  = TokenParser TypeParserState
    -> forall a. TypeParser a -> TypeParser a
    forall s u (m :: * -> *).
    GenTokenParser s u m
    -> forall a. ParsecT s u m a -> ParsecT s u m a
    P.brackets TokenParser TypeParserState
    lexer
    identifier :: TypeParser [Char]
    identifier= TokenParser TypeParserState -> TypeParser [Char]
    forall s u (m :: * -> *).
    GenTokenParser s u m -> ParsecT s u m [Char]
    P.identifier TokenParser TypeParserState
    lexer
    reservedOp :: [Char] -> TypeParser ()
    reservedOp= TokenParser TypeParserState -> [Char] -> TypeParser ()
    forall s u (m :: * -> *).
    GenTokenParser s u m -> [Char] -> ParsecT s u m ()
    P.reservedOp TokenParser TypeParserState
    lexer
    commaSep1 :: forall a. TypeParser a -> TypeParser [a]
    commaSep1 = TokenParser TypeParserState
    -> forall a. TypeParser a -> TypeParser [a]
    forall s u (m :: * -> *).
    GenTokenParser s u m
    -> forall a. ParsecT s u m a -> ParsecT s u m [a]
    P.commaSep1 TokenParser TypeParserState
    lexer
    commaSep :: forall a. TypeParser a -> TypeParser [a]
    commaSep  = TokenParser TypeParserState
    -> forall a. TypeParser a -> TypeParser [a]
    forall s u (m :: * -> *).
    GenTokenParser s u m
    -> forall a. ParsecT s u m a -> ParsecT s u m [a]
    P.commaSep  TokenParser TypeParserState
    lexer

    lexeme :: forall a. TypeParser a -> TypeParser a
    lexeme    = TokenParser TypeParserState
    -> forall a. TypeParser a -> TypeParser a
    forall s u (m :: * -> *).
    GenTokenParser s u m
    -> forall a. ParsecT s u m a -> ParsecT s u m a
    P.lexeme TokenParser TypeParserState
    lexer

    parseType :: String -> Either ParseError JType
    parseType :: [Char] -> Either ParseError JType
    parseType [Char]
    s = GenParser Char TypeParserState JType
    -> TypeParserState -> [Char] -> [Char] -> Either ParseError JType
    forall tok st a.
    GenParser tok st a -> st -> [Char] -> [tok] -> Either ParseError a
    runParser GenParser Char TypeParserState JType
    anyType (Int
    0,Map [Char] Int
    forall k a. Map k a
    M.empty) [Char]
    "" [Char]
    s

    parseConstrainedType :: String -> Either ParseError JLocalType
    parseConstrainedType :: [Char] -> Either ParseError JLocalType
    parseConstrainedType [Char]
    s = GenParser Char TypeParserState JLocalType
    -> TypeParserState
    -> [Char]
    -> [Char]
    -> Either ParseError JLocalType
    forall tok st a.
    GenParser tok st a -> st -> [Char] -> [tok] -> Either ParseError a
    runParser GenParser Char TypeParserState JLocalType
    constrainedType (Int
    0,Map [Char] Int
    forall k a. Map k a
    M.empty) [Char]
    "" [Char]
    s

    runTypeParser :: CharParser a JLocalType
    runTypeParser :: forall a. CharParser a JLocalType
    runTypeParser = TypeParserState
    -> GenParser Char TypeParserState JLocalType
    -> ParsecT [Char] a Identity JLocalType
    forall (m :: * -> *) st s a st'.
    (Functor m, Monad m) =>
    st -> ParsecT s st m a -> ParsecT s st' m a
    withLocalState (Int
    0,Map [Char] Int
    forall k a. Map k a
    M.empty) (GenParser Char TypeParserState JLocalType
    -> GenParser Char TypeParserState JLocalType
    forall tok st a. GenParser tok st a -> GenParser tok st a
    try (GenParser Char TypeParserState JLocalType
    -> GenParser Char TypeParserState JLocalType
    forall a. TypeParser a -> TypeParser a
    parens GenParser Char TypeParserState JLocalType
    constrainedType) GenParser Char TypeParserState JLocalType
    -> GenParser Char TypeParserState JLocalType
    -> GenParser Char TypeParserState JLocalType
    forall s u (m :: * -> *) a.
    ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
    <|> GenParser Char TypeParserState JLocalType
    constrainedType) -- anyType

    withLocalState :: (Functor m, Monad m) => st -> ParsecT s st m a -> ParsecT s st' m a
    withLocalState :: forall (m :: * -> *) st s a st'.
    (Functor m, Monad m) =>
    st -> ParsecT s st m a -> ParsecT s st' m a
    withLocalState st
    initState ParsecT s st m a
    subParser = (State s st' -> m (Consumed (m (Reply s st' a))))
    -> ParsecT s st' m a
    forall (m :: * -> *) s u a.
    Monad m =>
    (State s u -> m (Consumed (m (Reply s u a)))) -> ParsecT s u m a
    mkPT ((State s st' -> m (Consumed (m (Reply s st' a))))
     -> ParsecT s st' m a)
    -> (State s st' -> m (Consumed (m (Reply s st' a))))
    -> ParsecT s st' m a
    forall a b. (a -> b) -> a -> b
    $
        \(State s
    input SourcePos
    pos st'
    otherState) -> st' -> Consumed (m (Reply s st a)) -> Consumed (m (Reply s st' a))
    forall {f :: * -> *} {f :: * -> *} {p} {s} {u} {a}.
    (Functor f, Functor f) =>
    p -> f (f (Reply s u a)) -> f (f (Reply s p a))
    fixState st'
    otherState (Consumed (m (Reply s st a)) -> Consumed (m (Reply s st' a)))
    -> m (Consumed (m (Reply s st a)))
    -> m (Consumed (m (Reply s st' a)))
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    <$> ParsecT s st m a -> State s st -> m (Consumed (m (Reply s st a)))
    forall (m :: * -> *) s u a.
    Monad m =>
    ParsecT s u m a -> State s u -> m (Consumed (m (Reply s u a)))
    runParsecT ParsecT s st m a
    subParser (s -> SourcePos -> st -> State s st
    forall s u. s -> SourcePos -> u -> State s u
    State s
    input SourcePos
    pos st
    initState)
          where
            fixState :: p -> f (f (Reply s u a)) -> f (f (Reply s p a))
    fixState p
    s f (f (Reply s u a))
    res = ((f (Reply s u a) -> f (Reply s p a))
    -> f (f (Reply s u a)) -> f (f (Reply s p a))
    forall a b. (a -> b) -> f a -> f b
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    fmap ((f (Reply s u a) -> f (Reply s p a))
     -> f (f (Reply s u a)) -> f (f (Reply s p a)))
    -> ((Reply s u a -> Reply s p a)
        -> f (Reply s u a) -> f (Reply s p a))
    -> (Reply s u a -> Reply s p a)
    -> f (f (Reply s u a))
    -> f (f (Reply s p a))
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . (Reply s u a -> Reply s p a) -> f (Reply s u a) -> f (Reply s p a)
    forall a b. (a -> b) -> f a -> f b
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    fmap) Reply s u a -> Reply s p a
    forall {s} {u} {a}. Reply s u a -> Reply s p a
    go f (f (Reply s u a))
    res
                where go :: Reply s u a -> Reply s p a
    go (Ok a
    a (State s
    input SourcePos
    pos u
    _localState) ParseError
    pe) = a -> State s p -> ParseError -> Reply s p a
    forall s u a. a -> State s u -> ParseError -> Reply s u a
    Ok a
    a (s -> SourcePos -> p -> State s p
    forall s u. s -> SourcePos -> u -> State s u
    State s
    input SourcePos
    pos p
    s) ParseError
    pe
                      go (Error ParseError
    e) = (ParseError -> Reply s p a
    forall s u a. ParseError -> Reply s u a
    Error ParseError
    e)

    constrainedType :: TypeParser JLocalType
    constrainedType :: GenParser Char TypeParserState JLocalType
    constrainedType = do
      c <- GenParser Char TypeParserState (Maybe [(VarRef, Constraint)])
    -> GenParser Char TypeParserState (Maybe [(VarRef, Constraint)])
    forall tok st a. GenParser tok st a -> GenParser tok st a
    try ([(VarRef, Constraint)] -> Maybe [(VarRef, Constraint)]
    forall a. a -> Maybe a
    Just ([(VarRef, Constraint)] -> Maybe [(VarRef, Constraint)])
    -> ParsecT [Char] TypeParserState Identity [(VarRef, Constraint)]
    -> GenParser Char TypeParserState (Maybe [(VarRef, Constraint)])
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    <$> (ParsecT [Char] TypeParserState Identity [(VarRef, Constraint)]
    constraintHead ParsecT [Char] TypeParserState Identity [(VarRef, Constraint)]
    -> TypeParser ()
    -> ParsecT [Char] TypeParserState Identity [(VarRef, Constraint)]
    forall a b.
    ParsecT [Char] TypeParserState Identity a
    -> ParsecT [Char] TypeParserState Identity b
    -> ParsecT [Char] TypeParserState Identity a
    forall (f :: * -> *) a b. Applicative f => f a -> f b -> f a
    <* [Char] -> TypeParser ()
    reservedOp [Char]
    "=>")) GenParser Char TypeParserState (Maybe [(VarRef, Constraint)])
    -> GenParser Char TypeParserState (Maybe [(VarRef, Constraint)])
    -> GenParser Char TypeParserState (Maybe [(VarRef, Constraint)])
    forall s u (m :: * -> *) a.
    ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
    <|> Maybe [(VarRef, Constraint)]
    -> GenParser Char TypeParserState (Maybe [(VarRef, Constraint)])
    forall a. a -> ParsecT [Char] TypeParserState Identity a
    forall (m :: * -> *) a. Monad m => a -> m a
    return Maybe [(VarRef, Constraint)]
    forall a. Maybe a
    Nothing
      t <- anyType
      return (fromMaybe [] c, t)

    --do we need to read supertype constraints, i.e. subtype constraints which have the freevar on the right??
    constraintHead :: TypeParser [(VarRef,Constraint)]
    constraintHead :: ParsecT [Char] TypeParserState Identity [(VarRef, Constraint)]
    constraintHead = ParsecT [Char] TypeParserState Identity [(VarRef, Constraint)]
    -> ParsecT [Char] TypeParserState Identity [(VarRef, Constraint)]
    forall a. TypeParser a -> TypeParser a
    parens ParsecT [Char] TypeParserState Identity [(VarRef, Constraint)]
    go ParsecT [Char] TypeParserState Identity [(VarRef, Constraint)]
    -> ParsecT [Char] TypeParserState Identity [(VarRef, Constraint)]
    -> ParsecT [Char] TypeParserState Identity [(VarRef, Constraint)]
    forall s u (m :: * -> *) a.
    ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
    <|> ParsecT [Char] TypeParserState Identity [(VarRef, Constraint)]
    go
        where go :: ParsecT [Char] TypeParserState Identity [(VarRef, Constraint)]
    go = TypeParser (VarRef, Constraint)
    -> ParsecT [Char] TypeParserState Identity [(VarRef, Constraint)]
    forall a. TypeParser a -> TypeParser [a]
    commaSep1 TypeParser (VarRef, Constraint)
    constraint
              constraint :: TypeParser (VarRef, Constraint)
    constraint = do
                r <- [Char] -> TypeParser VarRef
    freeVarRef ([Char] -> TypeParser VarRef)
    -> TypeParser [Char] -> TypeParser VarRef
    forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
    =<< TypeParser [Char]
    identifier
                c <- (reservedOp "<:" >> (return Sub)) <|>
                     (reservedOp ":>" >> (return Super))
                t <- anyType
                return $ (r, c t)

    anyType :: TypeParser JType
    anyType :: GenParser Char TypeParserState JType
    anyType = GenParser Char TypeParserState JType
    -> GenParser Char TypeParserState JType
    forall tok st a. GenParser tok st a -> GenParser tok st a
    try (GenParser Char TypeParserState JType
    -> GenParser Char TypeParserState JType
    forall a. TypeParser a -> TypeParser a
    parens GenParser Char TypeParserState JType
    anyType) GenParser Char TypeParserState JType
    -> GenParser Char TypeParserState JType
    -> GenParser Char TypeParserState JType
    forall s u (m :: * -> *) a.
    ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
    <|> GenParser Char TypeParserState JType
    funOrAtomType GenParser Char TypeParserState JType
    -> GenParser Char TypeParserState JType
    -> GenParser Char TypeParserState JType
    forall s u (m :: * -> *) a.
    ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
    <|> GenParser Char TypeParserState JType
    listType GenParser Char TypeParserState JType
    -> GenParser Char TypeParserState JType
    -> GenParser Char TypeParserState JType
    forall s u (m :: * -> *) a.
    ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
    <|> GenParser Char TypeParserState JType
    recordType

    funOrAtomType :: TypeParser JType
    funOrAtomType :: GenParser Char TypeParserState JType
    funOrAtomType = do
      r <- GenParser Char TypeParserState JType
    anyNestedType GenParser Char TypeParserState JType
    -> TypeParser [Char]
    -> ParsecT [Char] TypeParserState Identity [JType]
    forall s (m :: * -> *) t u a sep.
    Stream s m t =>
    ParsecT s u m a -> ParsecT s u m sep -> ParsecT s u m [a]
    `sepBy1` (TypeParser [Char] -> TypeParser [Char]
    forall a. TypeParser a -> TypeParser a
    lexeme ([Char] -> TypeParser [Char]
    forall s (m :: * -> *) u.
    Stream s m Char =>
    [Char] -> ParsecT s u m [Char]
    string [Char]
    "->"))
      return $ case reverse r of
        [JType
    x] -> JType
    x
        (JType
    x:[JType]
    xs) -> [JType] -> JType -> JType
    JTFunc ([JType] -> [JType]
    forall a. [a] -> [a]
    reverse [JType]
    xs) JType
    x
        [JType]
    _ -> [Char] -> JType
    forall a. HasCallStack => [Char] -> a
    error [Char]
    "funOrAtomType"

    listType :: TypeParser JType
    listType :: GenParser Char TypeParserState JType
    listType = JType -> JType
    JTList (JType -> JType)
    -> GenParser Char TypeParserState JType
    -> GenParser Char TypeParserState JType
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    <$> GenParser Char TypeParserState JType
    -> GenParser Char TypeParserState JType
    forall a. TypeParser a -> TypeParser a
    brackets GenParser Char TypeParserState JType
    anyType

    anyNestedType :: TypeParser JType
    anyNestedType :: GenParser Char TypeParserState JType
    anyNestedType = GenParser Char TypeParserState JType
    nullType GenParser Char TypeParserState JType
    -> GenParser Char TypeParserState JType
    -> GenParser Char TypeParserState JType
    forall s u (m :: * -> *) a.
    ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
    <|> GenParser Char TypeParserState JType
    -> GenParser Char TypeParserState JType
    forall a. TypeParser a -> TypeParser a
    parens GenParser Char TypeParserState JType
    anyType GenParser Char TypeParserState JType
    -> GenParser Char TypeParserState JType
    -> GenParser Char TypeParserState JType
    forall s u (m :: * -> *) a.
    ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
    <|> GenParser Char TypeParserState JType
    atomicType GenParser Char TypeParserState JType
    -> GenParser Char TypeParserState JType
    -> GenParser Char TypeParserState JType
    forall s u (m :: * -> *) a.
    ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
    <|> GenParser Char TypeParserState JType
    listType GenParser Char TypeParserState JType
    -> GenParser Char TypeParserState JType
    -> GenParser Char TypeParserState JType
    forall s u (m :: * -> *) a.
    ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
    <|> GenParser Char TypeParserState JType
    recordType

    nullType :: TypeParser JType
    nullType :: GenParser Char TypeParserState JType
    nullType = [Char] -> TypeParser ()
    reservedOp [Char]
    "()" TypeParser ()
    -> GenParser Char TypeParserState JType
    -> GenParser Char TypeParserState JType
    forall a b.
    ParsecT [Char] TypeParserState Identity a
    -> ParsecT [Char] TypeParserState Identity b
    -> ParsecT [Char] TypeParserState Identity b
    forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
    >> JType -> GenParser Char TypeParserState JType
    forall a. a -> ParsecT [Char] TypeParserState Identity a
    forall (m :: * -> *) a. Monad m => a -> m a
    return JType
    JTStat

    atomicType :: TypeParser JType
    atomicType :: GenParser Char TypeParserState JType
    atomicType = do
      a <- TypeParser [Char]
    identifier
      case a of
        [Char]
    "Num" -> JType -> GenParser Char TypeParserState JType
    forall a. a -> ParsecT [Char] TypeParserState Identity a
    forall (m :: * -> *) a. Monad m => a -> m a
    return JType
    JTNum
        [Char]
    "String" -> JType -> GenParser Char TypeParserState JType
    forall a. a -> ParsecT [Char] TypeParserState Identity a
    forall (m :: * -> *) a. Monad m => a -> m a
    return JType
    JTString
        [Char]
    "Bool" -> JType -> GenParser Char TypeParserState JType
    forall a. a -> ParsecT [Char] TypeParserState Identity a
    forall (m :: * -> *) a. Monad m => a -> m a
    return JType
    JTBool
        (Char
    x:[Char]
    _) | Char -> Bool
    isUpper Char
    x -> [Char] -> GenParser Char TypeParserState JType
    forall a. [Char] -> ParsecT [Char] TypeParserState Identity a
    forall (m :: * -> *) a. MonadFail m => [Char] -> m a
    fail ([Char] -> GenParser Char TypeParserState JType)
    -> [Char] -> GenParser Char TypeParserState JType
    forall a b. (a -> b) -> a -> b
    $ [Char]
    "Unknown type: " [Char] -> ShowS
    forall a. [a] -> [a] -> [a]
    ++ [Char]
    a
              | Bool
    otherwise -> VarRef -> JType
    JTFree (VarRef -> JType)
    -> TypeParser VarRef -> GenParser Char TypeParserState JType
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    <$> [Char] -> TypeParser VarRef
    freeVarRef [Char]
    a
        [Char]
    _ -> [Char] -> GenParser Char TypeParserState JType
    forall a. HasCallStack => [Char] -> a
    error [Char]
    "typeAtom"

    recordType :: TypeParser JType
    recordType :: GenParser Char TypeParserState JType
    recordType = GenParser Char TypeParserState JType
    -> GenParser Char TypeParserState JType
    forall a. TypeParser a -> TypeParser a
    braces (GenParser Char TypeParserState JType
     -> GenParser Char TypeParserState JType)
    -> GenParser Char TypeParserState JType
    -> GenParser Char TypeParserState JType
    forall a b. (a -> b) -> a -> b
    $ JType -> Map [Char] JType -> JType
    JTRecord JType
    JTImpossible (Map [Char] JType -> JType)
    -> ([([Char], JType)] -> Map [Char] JType)
    -> [([Char], JType)]
    -> JType
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . [([Char], JType)] -> Map [Char] JType
    forall k a. Ord k => [(k, a)] -> Map k a
    M.fromList ([([Char], JType)] -> JType)
    -> ParsecT [Char] TypeParserState Identity [([Char], JType)]
    -> GenParser Char TypeParserState JType
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    <$> TypeParser ([Char], JType)
    -> ParsecT [Char] TypeParserState Identity [([Char], JType)]
    forall a. TypeParser a -> TypeParser [a]
    commaSep TypeParser ([Char], JType)
    namePair
        where namePair :: TypeParser ([Char], JType)
    namePair = do
                n <- TypeParser [Char]
    identifier
                reservedOp "::"
                t <- anyType
                return (n, t)

    freeVarRef :: String -> TypeParser VarRef
    freeVarRef :: [Char] -> TypeParser VarRef
    freeVarRef [Char]
    v = do
      (i,m) <- ParsecT [Char] TypeParserState Identity TypeParserState
    forall (m :: * -> *) s u. Monad m => ParsecT s u m u
    getState
      (\Int
    x -> ([Char] -> Maybe [Char]
    forall a. a -> Maybe a
    Just [Char]
    v, Int
    x)) <$> maybe (setState (i+1,M.insert v i m) >> return i)
                                     return
                                     (M.lookup v m)