packages feed

purescript 0.6.0.2 → 0.6.1

raw patch · 51 files changed

+2152/−1695 lines, 51 filesPVP: major bump suggested

API removals or changes: PVP suggests a major version bump

API changes (from Hackage documentation)

- Language.PureScript.Declarations: Abs :: (Either Ident Binder) -> Expr -> Expr
- Language.PureScript.Declarations: Accessor :: String -> Expr -> Expr
- Language.PureScript.Declarations: App :: Expr -> Expr -> Expr
- Language.PureScript.Declarations: ArrayBinder :: [Binder] -> Binder
- Language.PureScript.Declarations: ArrayLiteral :: [Expr] -> Expr
- Language.PureScript.Declarations: BinaryNoParens :: (Qualified Ident) -> Expr -> Expr -> Expr
- Language.PureScript.Declarations: BindingGroupDeclaration :: [(Ident, NameKind, Expr)] -> Declaration
- Language.PureScript.Declarations: BooleanBinder :: Bool -> Binder
- Language.PureScript.Declarations: BooleanLiteral :: Bool -> Expr
- Language.PureScript.Declarations: Case :: [Expr] -> [CaseAlternative] -> Expr
- Language.PureScript.Declarations: CaseAlternative :: [Binder] -> Maybe Guard -> Expr -> CaseAlternative
- Language.PureScript.Declarations: ConsBinder :: Binder -> Binder -> Binder
- Language.PureScript.Declarations: Constructor :: (Qualified ProperName) -> Expr
- Language.PureScript.Declarations: ConstructorBinder :: (Qualified ProperName) -> [Binder] -> Binder
- Language.PureScript.Declarations: DataBindingGroupDeclaration :: [Declaration] -> Declaration
- Language.PureScript.Declarations: DataDeclaration :: DataDeclType -> ProperName -> [(String, Maybe Kind)] -> [(ProperName, [Type])] -> Declaration
- Language.PureScript.Declarations: Do :: [DoNotationElement] -> Expr
- Language.PureScript.Declarations: DoNotationBind :: Binder -> Expr -> DoNotationElement
- Language.PureScript.Declarations: DoNotationLet :: [Declaration] -> DoNotationElement
- Language.PureScript.Declarations: DoNotationValue :: Expr -> DoNotationElement
- Language.PureScript.Declarations: ExternDataDeclaration :: ProperName -> Kind -> Declaration
- Language.PureScript.Declarations: ExternDeclaration :: ForeignImportType -> Ident -> (Maybe JS) -> Type -> Declaration
- Language.PureScript.Declarations: ExternInstanceDeclaration :: Ident -> [(Qualified ProperName, [Type])] -> (Qualified ProperName) -> [Type] -> Declaration
- Language.PureScript.Declarations: Fixity :: Associativity -> Precedence -> Fixity
- Language.PureScript.Declarations: FixityDeclaration :: Fixity -> String -> Declaration
- Language.PureScript.Declarations: Hiding :: [DeclarationRef] -> ImportDeclarationType
- Language.PureScript.Declarations: IfThenElse :: Expr -> Expr -> Expr -> Expr
- Language.PureScript.Declarations: ImportDeclaration :: ModuleName -> ImportDeclarationType -> (Maybe ModuleName) -> Declaration
- Language.PureScript.Declarations: Infix :: Associativity
- Language.PureScript.Declarations: Infixl :: Associativity
- Language.PureScript.Declarations: Infixr :: Associativity
- Language.PureScript.Declarations: Let :: [Declaration] -> Expr -> Expr
- Language.PureScript.Declarations: Module :: ModuleName -> [Declaration] -> (Maybe [DeclarationRef]) -> Module
- Language.PureScript.Declarations: NamedBinder :: Ident -> Binder -> Binder
- Language.PureScript.Declarations: NullBinder :: Binder
- Language.PureScript.Declarations: NumberBinder :: (Either Integer Double) -> Binder
- Language.PureScript.Declarations: NumericLiteral :: (Either Integer Double) -> Expr
- Language.PureScript.Declarations: ObjectBinder :: [(String, Binder)] -> Binder
- Language.PureScript.Declarations: ObjectLiteral :: [(String, Expr)] -> Expr
- Language.PureScript.Declarations: ObjectUpdate :: Expr -> [(String, Expr)] -> Expr
- Language.PureScript.Declarations: Parens :: Expr -> Expr
- Language.PureScript.Declarations: PositionedBinder :: SourcePos -> Binder -> Binder
- Language.PureScript.Declarations: PositionedDeclaration :: SourcePos -> Declaration -> Declaration
- Language.PureScript.Declarations: PositionedDeclarationRef :: SourcePos -> DeclarationRef -> DeclarationRef
- Language.PureScript.Declarations: PositionedDoNotationElement :: SourcePos -> DoNotationElement -> DoNotationElement
- Language.PureScript.Declarations: PositionedValue :: SourcePos -> Expr -> Expr
- Language.PureScript.Declarations: Qualifying :: [DeclarationRef] -> ImportDeclarationType
- Language.PureScript.Declarations: SourcePos :: String -> Int -> Int -> SourcePos
- Language.PureScript.Declarations: StringBinder :: String -> Binder
- Language.PureScript.Declarations: StringLiteral :: String -> Expr
- Language.PureScript.Declarations: SuperClassDictionary :: (Qualified ProperName) -> [Type] -> Expr
- Language.PureScript.Declarations: TypeClassDeclaration :: ProperName -> [(String, Maybe Kind)] -> [(Qualified ProperName, [Type])] -> [Declaration] -> Declaration
- Language.PureScript.Declarations: TypeClassDictionary :: Bool -> (Qualified ProperName, [Type]) -> [TypeClassDictionaryInScope] -> Expr
- Language.PureScript.Declarations: TypeClassDictionaryConstructorApp :: (Qualified ProperName) -> Expr -> Expr
- Language.PureScript.Declarations: TypeClassRef :: ProperName -> DeclarationRef
- Language.PureScript.Declarations: TypeDeclaration :: Ident -> Type -> Declaration
- Language.PureScript.Declarations: TypeInstanceDeclaration :: Ident -> [(Qualified ProperName, [Type])] -> (Qualified ProperName) -> [Type] -> [Declaration] -> Declaration
- Language.PureScript.Declarations: TypeInstanceRef :: Ident -> DeclarationRef
- Language.PureScript.Declarations: TypeRef :: ProperName -> (Maybe [ProperName]) -> DeclarationRef
- Language.PureScript.Declarations: TypeSynonymDeclaration :: ProperName -> [(String, Maybe Kind)] -> Type -> Declaration
- Language.PureScript.Declarations: TypedValue :: Bool -> Expr -> Type -> Expr
- Language.PureScript.Declarations: UnaryMinus :: Expr -> Expr
- Language.PureScript.Declarations: Unqualified :: ImportDeclarationType
- Language.PureScript.Declarations: ValueDeclaration :: Ident -> NameKind -> [Binder] -> (Maybe Guard) -> Expr -> Declaration
- Language.PureScript.Declarations: ValueRef :: Ident -> DeclarationRef
- Language.PureScript.Declarations: Var :: (Qualified Ident) -> Expr
- Language.PureScript.Declarations: VarBinder :: Ident -> Binder
- Language.PureScript.Declarations: accumTypes :: Monoid r => (Type -> r) -> (Declaration -> r, Expr -> r, Binder -> r, CaseAlternative -> r, DoNotationElement -> r)
- Language.PureScript.Declarations: binderNames :: Binder -> [Ident]
- Language.PureScript.Declarations: canonicalizeDictionary :: TypeClassDictionaryInScope -> Qualified Ident
- Language.PureScript.Declarations: caseAlternativeBinders :: CaseAlternative -> [Binder]
- Language.PureScript.Declarations: caseAlternativeGuard :: CaseAlternative -> Maybe Guard
- Language.PureScript.Declarations: caseAlternativeResult :: CaseAlternative -> Expr
- Language.PureScript.Declarations: data Associativity
- Language.PureScript.Declarations: data Binder
- Language.PureScript.Declarations: data CaseAlternative
- Language.PureScript.Declarations: data Declaration
- Language.PureScript.Declarations: data DeclarationRef
- Language.PureScript.Declarations: data DoNotationElement
- Language.PureScript.Declarations: data Expr
- Language.PureScript.Declarations: data Fixity
- Language.PureScript.Declarations: data ImportDeclarationType
- Language.PureScript.Declarations: data Module
- Language.PureScript.Declarations: data SourcePos
- Language.PureScript.Declarations: everythingOnValues :: (r -> r -> r) -> (Declaration -> r) -> (Expr -> r) -> (Binder -> r) -> (CaseAlternative -> r) -> (DoNotationElement -> r) -> (Declaration -> r, Expr -> r, Binder -> r, CaseAlternative -> r, DoNotationElement -> r)
- Language.PureScript.Declarations: everythingWithContextOnValues :: s -> r -> (r -> r -> r) -> (s -> Declaration -> (s, r)) -> (s -> Expr -> (s, r)) -> (s -> Binder -> (s, r)) -> (s -> CaseAlternative -> (s, r)) -> (s -> DoNotationElement -> (s, r)) -> (Declaration -> r, Expr -> r, Binder -> r, CaseAlternative -> r, DoNotationElement -> r)
- Language.PureScript.Declarations: everywhereOnValues :: (Declaration -> Declaration) -> (Expr -> Expr) -> (Binder -> Binder) -> (Declaration -> Declaration, Expr -> Expr, Binder -> Binder)
- Language.PureScript.Declarations: everywhereOnValuesM :: (Functor m, Applicative m, Monad m) => (Declaration -> m Declaration) -> (Expr -> m Expr) -> (Binder -> m Binder) -> (Declaration -> m Declaration, Expr -> m Expr, Binder -> m Binder)
- Language.PureScript.Declarations: everywhereOnValuesTopDownM :: (Functor m, Applicative m, Monad m) => (Declaration -> m Declaration) -> (Expr -> m Expr) -> (Binder -> m Binder) -> (Declaration -> m Declaration, Expr -> m Expr, Binder -> m Binder)
- Language.PureScript.Declarations: everywhereWithContextOnValuesM :: (Functor m, Applicative m, Monad m) => s -> (s -> Declaration -> m (s, Declaration)) -> (s -> Expr -> m (s, Expr)) -> (s -> Binder -> m (s, Binder)) -> (s -> CaseAlternative -> m (s, CaseAlternative)) -> (s -> DoNotationElement -> m (s, DoNotationElement)) -> (Declaration -> m Declaration, Expr -> m Expr, Binder -> m Binder, CaseAlternative -> m CaseAlternative, DoNotationElement -> m DoNotationElement)
- Language.PureScript.Declarations: instance Data Associativity
- Language.PureScript.Declarations: instance Data Binder
- Language.PureScript.Declarations: instance Data CaseAlternative
- Language.PureScript.Declarations: instance Data Declaration
- Language.PureScript.Declarations: instance Data DeclarationRef
- Language.PureScript.Declarations: instance Data DoNotationElement
- Language.PureScript.Declarations: instance Data Expr
- Language.PureScript.Declarations: instance Data Fixity
- Language.PureScript.Declarations: instance Data ImportDeclarationType
- Language.PureScript.Declarations: instance Data Module
- Language.PureScript.Declarations: instance Data SourcePos
- Language.PureScript.Declarations: instance Eq DeclarationRef
- Language.PureScript.Declarations: instance Show Associativity
- Language.PureScript.Declarations: instance Show Binder
- Language.PureScript.Declarations: instance Show CaseAlternative
- Language.PureScript.Declarations: instance Show Declaration
- Language.PureScript.Declarations: instance Show DeclarationRef
- Language.PureScript.Declarations: instance Show DoNotationElement
- Language.PureScript.Declarations: instance Show Expr
- Language.PureScript.Declarations: instance Show Fixity
- Language.PureScript.Declarations: instance Show ImportDeclarationType
- Language.PureScript.Declarations: instance Show Module
- Language.PureScript.Declarations: instance Show SourcePos
- Language.PureScript.Declarations: instance Typeable Associativity
- Language.PureScript.Declarations: instance Typeable Binder
- Language.PureScript.Declarations: instance Typeable CaseAlternative
- Language.PureScript.Declarations: instance Typeable Declaration
- Language.PureScript.Declarations: instance Typeable DeclarationRef
- Language.PureScript.Declarations: instance Typeable DoNotationElement
- Language.PureScript.Declarations: instance Typeable Expr
- Language.PureScript.Declarations: instance Typeable Fixity
- Language.PureScript.Declarations: instance Typeable ImportDeclarationType
- Language.PureScript.Declarations: instance Typeable Module
- Language.PureScript.Declarations: instance Typeable SourcePos
- Language.PureScript.Declarations: isDataDecl :: Declaration -> Bool
- Language.PureScript.Declarations: isExternDataDecl :: Declaration -> Bool
- Language.PureScript.Declarations: isExternDecl :: Declaration -> Bool
- Language.PureScript.Declarations: isExternInstanceDecl :: Declaration -> Bool
- Language.PureScript.Declarations: isFixityDecl :: Declaration -> Bool
- Language.PureScript.Declarations: isImportDecl :: Declaration -> Bool
- Language.PureScript.Declarations: isTypeClassDeclaration :: Declaration -> Bool
- Language.PureScript.Declarations: isValueDecl :: Declaration -> Bool
- Language.PureScript.Declarations: sourceName :: SourcePos -> String
- Language.PureScript.Declarations: sourcePosColumn :: SourcePos -> Int
- Language.PureScript.Declarations: sourcePosLine :: SourcePos -> Int
- Language.PureScript.Declarations: type Guard = Expr
- Language.PureScript.Declarations: type Precedence = Integer
- Language.PureScript.TypeChecker.Types: instance Eq DictionaryValue
- Language.PureScript.TypeChecker.Types: instance Ord DictionaryValue
- Language.PureScript.TypeChecker.Types: instance Partial Type
- Language.PureScript.TypeChecker.Types: instance Show DictionaryValue
- Language.PureScript.TypeChecker.Types: instance Unifiable Check Type
+ Language.PureScript.AST.Binders: ArrayBinder :: [Binder] -> Binder
+ Language.PureScript.AST.Binders: BooleanBinder :: Bool -> Binder
+ Language.PureScript.AST.Binders: ConsBinder :: Binder -> Binder -> Binder
+ Language.PureScript.AST.Binders: ConstructorBinder :: (Qualified ProperName) -> [Binder] -> Binder
+ Language.PureScript.AST.Binders: NamedBinder :: Ident -> Binder -> Binder
+ Language.PureScript.AST.Binders: NullBinder :: Binder
+ Language.PureScript.AST.Binders: NumberBinder :: (Either Integer Double) -> Binder
+ Language.PureScript.AST.Binders: ObjectBinder :: [(String, Binder)] -> Binder
+ Language.PureScript.AST.Binders: PositionedBinder :: SourcePos -> Binder -> Binder
+ Language.PureScript.AST.Binders: StringBinder :: String -> Binder
+ Language.PureScript.AST.Binders: VarBinder :: Ident -> Binder
+ Language.PureScript.AST.Binders: binderNames :: Binder -> [Ident]
+ Language.PureScript.AST.Binders: data Binder
+ Language.PureScript.AST.Binders: instance Data Binder
+ Language.PureScript.AST.Binders: instance Show Binder
+ Language.PureScript.AST.Binders: instance Typeable Binder
+ Language.PureScript.AST.Declarations: Abs :: (Either Ident Binder) -> Expr -> Expr
+ Language.PureScript.AST.Declarations: Accessor :: String -> Expr -> Expr
+ Language.PureScript.AST.Declarations: App :: Expr -> Expr -> Expr
+ Language.PureScript.AST.Declarations: ArrayLiteral :: [Expr] -> Expr
+ Language.PureScript.AST.Declarations: BinaryNoParens :: (Qualified Ident) -> Expr -> Expr -> Expr
+ Language.PureScript.AST.Declarations: BindingGroupDeclaration :: [(Ident, NameKind, Expr)] -> Declaration
+ Language.PureScript.AST.Declarations: BooleanLiteral :: Bool -> Expr
+ Language.PureScript.AST.Declarations: Case :: [Expr] -> [CaseAlternative] -> Expr
+ Language.PureScript.AST.Declarations: CaseAlternative :: [Binder] -> Either [(Guard, Expr)] Expr -> CaseAlternative
+ Language.PureScript.AST.Declarations: Constructor :: (Qualified ProperName) -> Expr
+ Language.PureScript.AST.Declarations: DataBindingGroupDeclaration :: [Declaration] -> Declaration
+ Language.PureScript.AST.Declarations: DataDeclaration :: DataDeclType -> ProperName -> [(String, Maybe Kind)] -> [(ProperName, [Type])] -> Declaration
+ Language.PureScript.AST.Declarations: Do :: [DoNotationElement] -> Expr
+ Language.PureScript.AST.Declarations: DoNotationBind :: Binder -> Expr -> DoNotationElement
+ Language.PureScript.AST.Declarations: DoNotationLet :: [Declaration] -> DoNotationElement
+ Language.PureScript.AST.Declarations: DoNotationValue :: Expr -> DoNotationElement
+ Language.PureScript.AST.Declarations: ExternDataDeclaration :: ProperName -> Kind -> Declaration
+ Language.PureScript.AST.Declarations: ExternDeclaration :: ForeignImportType -> Ident -> (Maybe JS) -> Type -> Declaration
+ Language.PureScript.AST.Declarations: ExternInstanceDeclaration :: Ident -> [(Qualified ProperName, [Type])] -> (Qualified ProperName) -> [Type] -> Declaration
+ Language.PureScript.AST.Declarations: FixityDeclaration :: Fixity -> String -> Declaration
+ Language.PureScript.AST.Declarations: Hiding :: [DeclarationRef] -> ImportDeclarationType
+ Language.PureScript.AST.Declarations: IfThenElse :: Expr -> Expr -> Expr -> Expr
+ Language.PureScript.AST.Declarations: ImportDeclaration :: ModuleName -> ImportDeclarationType -> (Maybe ModuleName) -> Declaration
+ Language.PureScript.AST.Declarations: Let :: [Declaration] -> Expr -> Expr
+ Language.PureScript.AST.Declarations: Module :: ModuleName -> [Declaration] -> (Maybe [DeclarationRef]) -> Module
+ Language.PureScript.AST.Declarations: NumericLiteral :: (Either Integer Double) -> Expr
+ Language.PureScript.AST.Declarations: ObjectLiteral :: [(String, Expr)] -> Expr
+ Language.PureScript.AST.Declarations: ObjectUpdate :: Expr -> [(String, Expr)] -> Expr
+ Language.PureScript.AST.Declarations: Parens :: Expr -> Expr
+ Language.PureScript.AST.Declarations: PositionedDeclaration :: SourcePos -> Declaration -> Declaration
+ Language.PureScript.AST.Declarations: PositionedDeclarationRef :: SourcePos -> DeclarationRef -> DeclarationRef
+ Language.PureScript.AST.Declarations: PositionedDoNotationElement :: SourcePos -> DoNotationElement -> DoNotationElement
+ Language.PureScript.AST.Declarations: PositionedValue :: SourcePos -> Expr -> Expr
+ Language.PureScript.AST.Declarations: Qualifying :: [DeclarationRef] -> ImportDeclarationType
+ Language.PureScript.AST.Declarations: StringLiteral :: String -> Expr
+ Language.PureScript.AST.Declarations: SuperClassDictionary :: (Qualified ProperName) -> [Type] -> Expr
+ Language.PureScript.AST.Declarations: TypeClassDeclaration :: ProperName -> [(String, Maybe Kind)] -> [(Qualified ProperName, [Type])] -> [Declaration] -> Declaration
+ Language.PureScript.AST.Declarations: TypeClassDictionary :: Bool -> (Qualified ProperName, [Type]) -> [TypeClassDictionaryInScope] -> Expr
+ Language.PureScript.AST.Declarations: TypeClassDictionaryConstructorApp :: (Qualified ProperName) -> Expr -> Expr
+ Language.PureScript.AST.Declarations: TypeClassRef :: ProperName -> DeclarationRef
+ Language.PureScript.AST.Declarations: TypeDeclaration :: Ident -> Type -> Declaration
+ Language.PureScript.AST.Declarations: TypeInstanceDeclaration :: Ident -> [(Qualified ProperName, [Type])] -> (Qualified ProperName) -> [Type] -> [Declaration] -> Declaration
+ Language.PureScript.AST.Declarations: TypeInstanceRef :: Ident -> DeclarationRef
+ Language.PureScript.AST.Declarations: TypeRef :: ProperName -> (Maybe [ProperName]) -> DeclarationRef
+ Language.PureScript.AST.Declarations: TypeSynonymDeclaration :: ProperName -> [(String, Maybe Kind)] -> Type -> Declaration
+ Language.PureScript.AST.Declarations: TypedValue :: Bool -> Expr -> Type -> Expr
+ Language.PureScript.AST.Declarations: UnaryMinus :: Expr -> Expr
+ Language.PureScript.AST.Declarations: Unqualified :: ImportDeclarationType
+ Language.PureScript.AST.Declarations: ValueDeclaration :: Ident -> NameKind -> [Binder] -> (Either [(Guard, Expr)] Expr) -> Declaration
+ Language.PureScript.AST.Declarations: ValueRef :: Ident -> DeclarationRef
+ Language.PureScript.AST.Declarations: Var :: (Qualified Ident) -> Expr
+ Language.PureScript.AST.Declarations: caseAlternativeBinders :: CaseAlternative -> [Binder]
+ Language.PureScript.AST.Declarations: caseAlternativeResult :: CaseAlternative -> Either [(Guard, Expr)] Expr
+ Language.PureScript.AST.Declarations: data CaseAlternative
+ Language.PureScript.AST.Declarations: data Declaration
+ Language.PureScript.AST.Declarations: data DeclarationRef
+ Language.PureScript.AST.Declarations: data DoNotationElement
+ Language.PureScript.AST.Declarations: data Expr
+ Language.PureScript.AST.Declarations: data ImportDeclarationType
+ Language.PureScript.AST.Declarations: data Module
+ Language.PureScript.AST.Declarations: instance Data CaseAlternative
+ Language.PureScript.AST.Declarations: instance Data Declaration
+ Language.PureScript.AST.Declarations: instance Data DeclarationRef
+ Language.PureScript.AST.Declarations: instance Data DoNotationElement
+ Language.PureScript.AST.Declarations: instance Data Expr
+ Language.PureScript.AST.Declarations: instance Data ImportDeclarationType
+ Language.PureScript.AST.Declarations: instance Data Module
+ Language.PureScript.AST.Declarations: instance Eq DeclarationRef
+ Language.PureScript.AST.Declarations: instance Show CaseAlternative
+ Language.PureScript.AST.Declarations: instance Show Declaration
+ Language.PureScript.AST.Declarations: instance Show DeclarationRef
+ Language.PureScript.AST.Declarations: instance Show DoNotationElement
+ Language.PureScript.AST.Declarations: instance Show Expr
+ Language.PureScript.AST.Declarations: instance Show ImportDeclarationType
+ Language.PureScript.AST.Declarations: instance Show Module
+ Language.PureScript.AST.Declarations: instance Typeable CaseAlternative
+ Language.PureScript.AST.Declarations: instance Typeable Declaration
+ Language.PureScript.AST.Declarations: instance Typeable DeclarationRef
+ Language.PureScript.AST.Declarations: instance Typeable DoNotationElement
+ Language.PureScript.AST.Declarations: instance Typeable Expr
+ Language.PureScript.AST.Declarations: instance Typeable ImportDeclarationType
+ Language.PureScript.AST.Declarations: instance Typeable Module
+ Language.PureScript.AST.Declarations: isDataDecl :: Declaration -> Bool
+ Language.PureScript.AST.Declarations: isExternDataDecl :: Declaration -> Bool
+ Language.PureScript.AST.Declarations: isExternDecl :: Declaration -> Bool
+ Language.PureScript.AST.Declarations: isExternInstanceDecl :: Declaration -> Bool
+ Language.PureScript.AST.Declarations: isFixityDecl :: Declaration -> Bool
+ Language.PureScript.AST.Declarations: isImportDecl :: Declaration -> Bool
+ Language.PureScript.AST.Declarations: isTypeClassDeclaration :: Declaration -> Bool
+ Language.PureScript.AST.Declarations: isValueDecl :: Declaration -> Bool
+ Language.PureScript.AST.Declarations: type Guard = Expr
+ Language.PureScript.AST.Operators: Fixity :: Associativity -> Precedence -> Fixity
+ Language.PureScript.AST.Operators: Infix :: Associativity
+ Language.PureScript.AST.Operators: Infixl :: Associativity
+ Language.PureScript.AST.Operators: Infixr :: Associativity
+ Language.PureScript.AST.Operators: data Associativity
+ Language.PureScript.AST.Operators: data Fixity
+ Language.PureScript.AST.Operators: instance Data Associativity
+ Language.PureScript.AST.Operators: instance Data Fixity
+ Language.PureScript.AST.Operators: instance Show Associativity
+ Language.PureScript.AST.Operators: instance Show Fixity
+ Language.PureScript.AST.Operators: instance Typeable Associativity
+ Language.PureScript.AST.Operators: instance Typeable Fixity
+ Language.PureScript.AST.Operators: type Precedence = Integer
+ Language.PureScript.AST.SourcePos: SourcePos :: String -> Int -> Int -> SourcePos
+ Language.PureScript.AST.SourcePos: data SourcePos
+ Language.PureScript.AST.SourcePos: instance Data SourcePos
+ Language.PureScript.AST.SourcePos: instance Show SourcePos
+ Language.PureScript.AST.SourcePos: instance Typeable SourcePos
+ Language.PureScript.AST.SourcePos: sourceName :: SourcePos -> String
+ Language.PureScript.AST.SourcePos: sourcePosColumn :: SourcePos -> Int
+ Language.PureScript.AST.SourcePos: sourcePosLine :: SourcePos -> Int
+ Language.PureScript.AST.Traversals: accumTypes :: Monoid r => (Type -> r) -> (Declaration -> r, Expr -> r, Binder -> r, CaseAlternative -> r, DoNotationElement -> r)
+ Language.PureScript.AST.Traversals: everythingOnValues :: (r -> r -> r) -> (Declaration -> r) -> (Expr -> r) -> (Binder -> r) -> (CaseAlternative -> r) -> (DoNotationElement -> r) -> (Declaration -> r, Expr -> r, Binder -> r, CaseAlternative -> r, DoNotationElement -> r)
+ Language.PureScript.AST.Traversals: everythingWithContextOnValues :: s -> r -> (r -> r -> r) -> (s -> Declaration -> (s, r)) -> (s -> Expr -> (s, r)) -> (s -> Binder -> (s, r)) -> (s -> CaseAlternative -> (s, r)) -> (s -> DoNotationElement -> (s, r)) -> (Declaration -> r, Expr -> r, Binder -> r, CaseAlternative -> r, DoNotationElement -> r)
+ Language.PureScript.AST.Traversals: everywhereOnValues :: (Declaration -> Declaration) -> (Expr -> Expr) -> (Binder -> Binder) -> (Declaration -> Declaration, Expr -> Expr, Binder -> Binder)
+ Language.PureScript.AST.Traversals: everywhereOnValuesM :: (Functor m, Applicative m, Monad m) => (Declaration -> m Declaration) -> (Expr -> m Expr) -> (Binder -> m Binder) -> (Declaration -> m Declaration, Expr -> m Expr, Binder -> m Binder)
+ Language.PureScript.AST.Traversals: everywhereOnValuesTopDownM :: (Functor m, Applicative m, Monad m) => (Declaration -> m Declaration) -> (Expr -> m Expr) -> (Binder -> m Binder) -> (Declaration -> m Declaration, Expr -> m Expr, Binder -> m Binder)
+ Language.PureScript.AST.Traversals: everywhereWithContextOnValuesM :: (Functor m, Applicative m, Monad m) => s -> (s -> Declaration -> m (s, Declaration)) -> (s -> Expr -> m (s, Expr)) -> (s -> Binder -> m (s, Binder)) -> (s -> CaseAlternative -> m (s, CaseAlternative)) -> (s -> DoNotationElement -> m (s, DoNotationElement)) -> (Declaration -> m Declaration, Expr -> m Expr, Binder -> m Binder, CaseAlternative -> m CaseAlternative, DoNotationElement -> m DoNotationElement)
+ Language.PureScript.Constants: unit :: String
+ Language.PureScript.Parser.Common: identifierName :: Parsec String u String
+ Language.PureScript.Parser.Types: noWildcards :: Parsec String ParseState Type -> Parsec String ParseState Type
+ Language.PureScript.Traversals: eitherM :: Applicative f => (a -> f c) -> (b -> f d) -> Either a b -> f (Either c d)
+ Language.PureScript.Traversals: pairM :: Applicative f => (a -> f c) -> (b -> f d) -> (a, b) -> f (c, d)
+ Language.PureScript.TypeChecker.Entailment: entails :: Environment -> ModuleName -> [TypeClassDictionaryInScope] -> (Qualified ProperName, [Type]) -> Bool -> Check Expr
+ Language.PureScript.TypeChecker.Entailment: instance Eq DictionaryValue
+ Language.PureScript.TypeChecker.Entailment: instance Ord DictionaryValue
+ Language.PureScript.TypeChecker.Entailment: instance Show DictionaryValue
+ Language.PureScript.TypeChecker.Rows: checkDuplicateLabels :: Expr -> Check ()
+ Language.PureScript.TypeChecker.Skolems: introduceSkolemScope :: Type -> UnifyT Type Check Type
+ Language.PureScript.TypeChecker.Skolems: newSkolemConstant :: UnifyT Type Check Int
+ Language.PureScript.TypeChecker.Skolems: newSkolemScope :: UnifyT Type Check SkolemScope
+ Language.PureScript.TypeChecker.Skolems: skolemEscapeCheck :: Expr -> Check ()
+ Language.PureScript.TypeChecker.Skolems: skolemize :: String -> Int -> SkolemScope -> Type -> Type
+ Language.PureScript.TypeChecker.Skolems: skolemizeTypesInValue :: String -> Int -> SkolemScope -> Expr -> Expr
+ Language.PureScript.TypeChecker.Subsumption: subsumes :: Maybe Expr -> Type -> Type -> UnifyT Type Check (Maybe Expr)
+ Language.PureScript.TypeChecker.Synonyms: desaturateAllTypeSynonyms :: Type -> Type
+ Language.PureScript.TypeChecker.Synonyms: expandAllTypeSynonyms :: (Error e, Functor m, Applicative m, Monad m, MonadState CheckState m, MonadError e m) => Type -> m Type
+ Language.PureScript.TypeChecker.Synonyms: expandTypeSynonym :: (Error e, Functor m, Monad m, MonadState CheckState m, MonadError e m) => Qualified ProperName -> [Type] -> m Type
+ Language.PureScript.TypeChecker.Synonyms: expandTypeSynonym' :: Environment -> Qualified ProperName -> [Type] -> Either String Type
+ Language.PureScript.TypeChecker.Synonyms: replaceAllTypeSynonyms :: (Error e, Functor m, Monad m, MonadState CheckState m, MonadError e m) => Type -> m Type
+ Language.PureScript.TypeChecker.Unify: instance Partial Type
+ Language.PureScript.TypeChecker.Unify: instance Unifiable Check Type
+ Language.PureScript.TypeChecker.Unify: replaceTypeWildcards :: Type -> UnifyT t Check Type
+ Language.PureScript.TypeChecker.Unify: replaceVarWithUnknown :: String -> Type -> UnifyT Type Check Type
+ Language.PureScript.TypeChecker.Unify: unifiesWith :: Environment -> Type -> Type -> Bool
+ Language.PureScript.TypeChecker.Unify: unifyRows :: Type -> Type -> UnifyT Type Check ()
+ Language.PureScript.TypeChecker.Unify: unifyTypes :: Type -> Type -> UnifyT Type Check ()
+ Language.PureScript.TypeChecker.Unify: varIfUnknown :: Type -> Type
+ Language.PureScript.TypeClassDictionaries: canonicalizeDictionary :: TypeClassDictionaryInScope -> Qualified Ident
+ Language.PureScript.Types: TypeWildcard :: Type
+ Language.PureScript.Types: containsWildcards :: Type -> Bool

Files

+ examples/failing/TypeWildcards1.purs view
@@ -0,0 +1,4 @@+module TypeWildcards where++type Test = _+
+ examples/failing/TypeWildcards2.purs view
@@ -0,0 +1,4 @@+module TypeWildcards where++data Test = Test _+
+ examples/failing/TypeWildcards3.purs view
@@ -0,0 +1,7 @@+module TypeWildcards where++data Foo a = Foo++instance showFoo :: Show (Foo _) where+  show Foo = "Foo"+
examples/passing/Guards.purs view
@@ -11,4 +11,13 @@     z | y > 0 -> z / 2     z -> z * 3 + 1 -  main = Debug.Trace.trace "Done"+  min :: forall a. (Ord a) => a -> a -> a+  min n m | n < m     = n+          | otherwise = m++  max :: forall a. (Ord a) => a -> a -> a+  max n m = case unit of+    _ | m < n     -> n+      | otherwise -> m++  main = Debug.Trace.trace $ min "Done" "ZZZZ"
+ examples/passing/ImplicitEmptyImport.purs view
@@ -0,0 +1,6 @@+module Main where++main = do+  Debug.Trace.trace "Hello"+  Debug.Trace.trace "Goodbye"+  Debug.Trace.trace "Done"
+ examples/passing/ReservedWords.purs view
@@ -0,0 +1,13 @@+-- See https://github.com/purescript/purescript/issues/606+module Main where++  o :: { type :: String }+  o = { type: "o" }++  p :: { type :: String }+  p = o { type = "p" }++  f :: forall r. { type :: String | r } -> String+  f { type = "p" } = "Done"++  main = Debug.Trace.trace $ f { type: p.type, foo: "bar" }
+ examples/passing/TypeWildcards.purs view
@@ -0,0 +1,13 @@+module Main where++testTopLevel :: _ -> _+testTopLevel n = n + 1++test :: forall a. (Eq a) => (a -> a) -> a -> a+test f a = go (f a) a+  where+  go :: _ -> _ -> _+  go a1 a2 | a1 == a2 = a1+  go a1 _ = go (f a1) a1++main = Debug.Trace.trace "Done"
prelude/prelude.purs view
@@ -1,5 +1,6 @@ module Prelude-  ( flip+  ( otherwise+  , flip   , const   , asTypeOf   , Semigroupoid, (<<<), (>>>)@@ -7,7 +8,7 @@   , ($), (#)   , (:), cons   , Show, show-  , Functor, (<$>), void+  , Functor, (<$>), (<#>), void   , Apply, (<*>)   , Applicative, pure, liftA1   , Bind, (>>=)@@ -23,6 +24,9 @@   , Unit(..), unit   ) where +  otherwise :: Boolean+  otherwise = true+   flip :: forall a b c. (a -> b -> c) -> b -> a -> c   flip f b a = f a b @@ -111,9 +115,13 @@     show = showArrayImpl show    infixl 4 <$>+  infixl 1 <#>    class Functor f where     (<$>) :: forall a b. (a -> b) -> f a -> f b++  (<#>) :: forall f a b. (Functor f) => f a -> (a -> b) -> f b+  (<#>) fa f = f <$> fa    void :: forall f a. (Functor f) => f a -> f Unit   void fa = const unit <$> fa
psci/Main.hs view
@@ -17,46 +17,41 @@  module Main where -import Commands+import Data.Foldable (traverse_)+import Data.List (intercalate, isPrefixOf, nub, sortBy, sort)+import Data.Maybe (mapMaybe)+import Data.Traversable (traverse)+import Data.Version (showVersion)+import qualified Data.Map as M  import Control.Applicative import Control.Monad+import Control.Monad.Error (ErrorT(..), MonadError)+import Control.Monad.Error.Class (MonadError(..)) import Control.Monad.Trans.Class import Control.Monad.Trans.Maybe (MaybeT(..), runMaybeT) import Control.Monad.Trans.State.Strict import qualified Control.Monad.Trans.State.Lazy as L-import Control.Monad.Error (ErrorT(..), MonadError)-import Control.Monad.Error.Class (MonadError(..)) -import Data.List (intercalate, isPrefixOf, nub, sortBy, sort)-import Data.Maybe (mapMaybe)-import Data.Foldable (traverse_)-import Data.Version (showVersion)-import Data.Traversable (traverse)--import Parser--import System.IO.Error (tryIOError) import System.Console.Haskeline-import System.Directory-       (createDirectoryIfMissing, getModificationTime, doesFileExist,-        findExecutable, getHomeDirectory, getCurrentDirectory)-import System.Process (readProcessWithExitCode)+import System.Directory (createDirectoryIfMissing, getModificationTime, doesFileExist, findExecutable, getHomeDirectory, getCurrentDirectory) import System.Exit-import System.FilePath-       (pathSeparator, takeDirectory, (</>), isPathSeparator)+import System.FilePath (pathSeparator, takeDirectory, (</>), isPathSeparator)+import System.IO.Error (tryIOError)+import System.Process (readProcessWithExitCode) import qualified System.Console.CmdTheLine as Cmd+import qualified System.IO.UTF8 as U (writeFile, putStrLn, print, readFile)  import Text.Parsec (ParseError) -import qualified Data.Map as M import qualified Language.PureScript as P-import qualified Paths_purescript as Paths-import qualified System.IO.UTF8 as U-       (writeFile, putStrLn, print, readFile)+import qualified Language.PureScript.AST as D import qualified Language.PureScript.Names as N-import qualified Language.PureScript.Declarations as D+import qualified Paths_purescript as Paths +import Commands+import Parser+ -- | -- The PSCI state. -- Holds a list of imported modules, loaded files, and partial let bindings.@@ -132,7 +127,7 @@ -- loadAllModules :: [FilePath] -> IO (Either ParseError [(Either P.RebuildPolicy FilePath, P.Module)]) loadAllModules files = do-  filesAndContent <- forM files $ \filename -> do +  filesAndContent <- forM files $ \filename -> do     content <- U.readFile filename     return (Right filename, content)   return $ P.parseModulesFromFiles (either (const "") id) $ (Left P.RebuildNever, P.prelude) : filesAndContent@@ -191,8 +186,8 @@     let matches = filter (isPrefixOf str) (names ms)     return $ sortBy sorter $ map simpleCompletion matches ++ files   getDeclName :: Maybe [P.DeclarationRef] -> P.Declaration -> Maybe P.Ident-  getDeclName Nothing (P.ValueDeclaration ident _ _ _ _) = Just ident-  getDeclName (Just exts) (P.ValueDeclaration ident _ _ _ _) | isExported = Just ident+  getDeclName Nothing (P.ValueDeclaration ident _ _ _) = Just ident+  getDeclName (Just exts) (P.ValueDeclaration ident _ _ _) | isExported = Just ident     where     isExported = any exports exts     exports (P.ValueRef ident') = ident == ident'@@ -236,9 +231,9 @@ instance P.MonadMake Make where   getTimestamp path = makeIO $ do     exists <- doesFileExist path-    case exists of-      True -> Just <$> getModificationTime path-      False -> return Nothing+    if exists+      then Just <$> getModificationTime path+      else return Nothing   readTextFile path = makeIO $ U.readFile path   writeTextFile path text = makeIO $ do     mkdirp path@@ -261,8 +256,8 @@     trace = P.Var (P.Qualified (Just traceModule) (P.Ident "print"))     itValue = foldl (\x f -> f x) value lets     mainValue = P.App trace (P.Var (P.Qualified Nothing (P.Ident "it")))-    itDecl = P.ValueDeclaration (P.Ident "it") P.Value [] Nothing itValue-    mainDecl = P.ValueDeclaration (P.Ident "main") P.Value [] Nothing mainValue+    itDecl = P.ValueDeclaration (P.Ident "it") P.Value [] $ Right itValue+    mainDecl = P.ValueDeclaration (P.Ident "main") P.Value [] $ Right mainValue     decls = if exec then [itDecl, mainDecl] else [itDecl]   in     P.Module moduleName ((importDecl `map` imports) ++ decls) Nothing@@ -307,7 +302,7 @@   case e of     Left err -> PSCI $ outputStrLn err     Right _ -> do-      psciIO $ writeFile indexFile $ "require('$PSCI').main();"+      psciIO $ writeFile indexFile "require('$PSCI').main();"       process <- psciIO findNodeProcess       result  <- psciIO $ traverse (\node -> readProcessWithExitCode node [indexFile] "") process       case result of@@ -316,6 +311,20 @@         Nothing                        -> PSCI $ outputStrLn "Couldn't find node.js"  -- |+-- Takes a let declaration and updates the environment, then run a make. If the declaration fails,+-- restore the pre-let environment.+--+handleLet :: (P.Expr -> P.Expr) -> PSCI ()+handleLet l = do+  st <- PSCI $ lift get+  let st' = updateLets l st+  let m = createTemporaryModule False st' (P.ObjectLiteral [])+  e <- psciIO . runMake $ P.make modulesDir options (psciLoadedModules st' ++ [(Left P.RebuildAlways, m)]) []+  case e of+    Left err -> PSCI $ outputStrLn err+    Right _ -> PSCI $ lift (put st')++-- | -- Show actual loaded modules in psci. -- handleShowLoadedModules :: PSCI ()@@ -444,7 +453,7 @@ handleCommand (Expression val) = handleDeclaration val handleCommand Help = PSCI $ outputStrLn helpMessage handleCommand (Import moduleName) = handleImport moduleName-handleCommand (Let l) = PSCI $ lift $ modify (updateLets l)+handleCommand (Let l) = handleLet l handleCommand (LoadFile filePath) = do   absPath <- psciIO $ expandTilde filePath   exists <- psciIO $ doesFileExist absPath@@ -460,7 +469,7 @@   files <- psciImportedFilenames <$> PSCI (lift get)   modulesOrFirstError <- psciIO $ loadAllModules files   case modulesOrFirstError of-    Left err -> psciIO $ putStrLn (show err) >> exitFailure+    Left err -> psciIO $ print err >> exitFailure     Right modules -> PSCI . lift $ put (PSCiState files defaultImports modules []) handleCommand (TypeOf val) = handleTypeOf val handleCommand (KindOf typ) = handleKindOf typ@@ -501,7 +510,7 @@   config <- loadUserConfig   modulesOrFirstError <- loadAllModules files   case modulesOrFirstError of-    Left err -> putStrLn (show err) >> exitFailure+    Left err -> print err >> exitFailure     Right modules -> do       historyFilename <- getHistoryFilename       let settings = defaultSettings { historyFile = Just historyFilename }
purescript.cabal view
@@ -1,7 +1,7 @@ name: purescript-version: 0.6.0.2+version: 0.6.1 cabal-version: >=1.8-build-type: Simple +build-type: Simple license: MIT license-file: LICENSE copyright: (c) 2013-14 Phil Freeman, (c) 2014 Gary Burgess, and other contributors@@ -24,54 +24,47 @@     location: https://github.com/purescript/purescript.git  library-    build-depends: base >=4 && <5, -                   cmdtheline == 0.2.*, -                   containers -any, +    build-depends: base >=4 && <5,+                   cmdtheline == 0.2.*,+                   containers -any,                    unordered-containers -any,-                   directory >= 1.2, -                   filepath -any, -                   mtl >= 2.1.0 && < 2.3.0, +                   directory >= 1.2,+                   filepath -any,+                   mtl >= 2.1.0 && < 2.3.0,                    parsec -any,-                   transformers >= 0.3 && < 0.5, +                   transformers >= 0.3 && < 0.5,                    utf8-string -any,                    pattern-arrows >= 0.0.2 && < 0.1,-                   monad-unify >= 0.2.2 && < 0.3, +                   monad-unify >= 0.2.2 && < 0.3,                    file-embed >= 0.0.7 && < 0.0.8,                    time -any     exposed-modules: Language.PureScript-                     Language.PureScript.Constants-                     Language.PureScript.Options-                     Language.PureScript.Declarations-                     Language.PureScript.Environment-                     Language.PureScript.Errors-                     Language.PureScript.Kinds-                     Language.PureScript.Names-                     Language.PureScript.Supply-                     Language.PureScript.Types-                     Language.PureScript.Traversals-                     Language.PureScript.TypeClassDictionaries-                     Language.PureScript.DeadCodeElimination-                     Language.PureScript.Sugar-                     Language.PureScript.ModuleDependencies-                     Language.PureScript.Sugar.CaseDeclarations-                     Language.PureScript.Sugar.DoNotation-                     Language.PureScript.Sugar.TypeDeclarations-                     Language.PureScript.Sugar.BindingGroups-                     Language.PureScript.Sugar.Operators-                     Language.PureScript.Sugar.TypeClasses-                     Language.PureScript.Sugar.Names+                     Language.PureScript.AST+                     Language.PureScript.AST.Binders+                     Language.PureScript.AST.Declarations+                     Language.PureScript.AST.Operators+                     Language.PureScript.AST.SourcePos+                     Language.PureScript.AST.Traversals                      Language.PureScript.CodeGen                      Language.PureScript.CodeGen.Common                      Language.PureScript.CodeGen.Externs                      Language.PureScript.CodeGen.JS                      Language.PureScript.CodeGen.JS.AST+                     Language.PureScript.Constants+                     Language.PureScript.DeadCodeElimination+                     Language.PureScript.Environment+                     Language.PureScript.Errors+                     Language.PureScript.Kinds+                     Language.PureScript.ModuleDependencies+                     Language.PureScript.Names                      Language.PureScript.Optimizer+                     Language.PureScript.Optimizer.Blocks                      Language.PureScript.Optimizer.Common+                     Language.PureScript.Optimizer.Inliner                      Language.PureScript.Optimizer.MagicDo                      Language.PureScript.Optimizer.TCO-                     Language.PureScript.Optimizer.Inliner                      Language.PureScript.Optimizer.Unused-                     Language.PureScript.Optimizer.Blocks+                     Language.PureScript.Options                      Language.PureScript.Parser                      Language.PureScript.Parser.Common                      Language.PureScript.Parser.Declarations@@ -85,11 +78,28 @@                      Language.PureScript.Pretty.Types                      Language.PureScript.Pretty.Values                      Language.PureScript.Renamer+                     Language.PureScript.Sugar+                     Language.PureScript.Sugar.BindingGroups+                     Language.PureScript.Sugar.CaseDeclarations+                     Language.PureScript.Sugar.DoNotation+                     Language.PureScript.Sugar.Names+                     Language.PureScript.Sugar.Operators+                     Language.PureScript.Sugar.TypeClasses+                     Language.PureScript.Sugar.TypeDeclarations+                     Language.PureScript.Supply+                     Language.PureScript.Traversals                      Language.PureScript.TypeChecker+                     Language.PureScript.TypeChecker.Entailment                      Language.PureScript.TypeChecker.Kinds                      Language.PureScript.TypeChecker.Monad+                     Language.PureScript.TypeChecker.Rows+                     Language.PureScript.TypeChecker.Skolems+                     Language.PureScript.TypeChecker.Subsumption                      Language.PureScript.TypeChecker.Synonyms                      Language.PureScript.TypeChecker.Types+                     Language.PureScript.TypeChecker.Unify+                     Language.PureScript.TypeClassDictionaries+                     Language.PureScript.Types     exposed: True     buildable: True     hs-source-dirs: src@@ -128,12 +138,12 @@                    Parser     ghc-options: -Wall -O2 -executable psc-docs +executable psc-docs     build-depends: base >=4 && <5, cmdtheline -any, purescript -any, utf8-string -any,                    process -any, mtl -any     main-is: Main.hs     buildable: True-    hs-source-dirs: psc-docs +    hs-source-dirs: psc-docs     other-modules:     ghc-options: -Wall -O2 
src/Language/PureScript.hs view
@@ -19,7 +19,7 @@  import Language.PureScript.Types as P import Language.PureScript.Kinds as P-import Language.PureScript.Declarations as P+import Language.PureScript.AST as P import Language.PureScript.Names as P import Language.PureScript.Parser as P import Language.PureScript.CodeGen as P@@ -139,7 +139,7 @@ data RebuildPolicy   -- | Never rebuild this module   = RebuildNever-  -- | Always rebuild this module +  -- | Always rebuild this module   | RebuildAlways deriving (Show, Eq, Ord)  -- |@@ -163,7 +163,7 @@      jsTimestamp <- getTimestamp jsFile     externsTimestamp <- getTimestamp externsFile-    inputTimestamp <- traverse getTimestamp inputFile +    inputTimestamp <- traverse getTimestamp inputFile      return $ case (inputTimestamp, jsTimestamp, externsTimestamp) of       (Right (Just t1), Just t2, Just t3) | t1 < min t2 t3 -> s
+ src/Language/PureScript/AST.hs view
@@ -0,0 +1,23 @@+-----------------------------------------------------------------------------+--+-- Module      :  Language.PureScript.AST+-- Copyright   :  (c) 2013-14 Phil Freeman, (c) 2014 Gary Burgess, and other contributors+-- License     :  MIT+--+-- Maintainer  :  Phil Freeman <paf31@cantab.net>+-- Stability   :  experimental+-- Portability :+--+-- | The initial PureScript AST+--+-----------------------------------------------------------------------------++module Language.PureScript.AST (+    module AST+) where++import Language.PureScript.AST.Binders as AST+import Language.PureScript.AST.Declarations as AST+import Language.PureScript.AST.Operators as AST+import Language.PureScript.AST.SourcePos as AST+import Language.PureScript.AST.Traversals as AST
+ src/Language/PureScript/AST/Binders.hs view
@@ -0,0 +1,86 @@+-----------------------------------------------------------------------------+--+-- Module      :  Language.PureScript.AST.Binders+-- Copyright   :  (c) 2013-14 Phil Freeman, (c) 2014 Gary Burgess, and other contributors+-- License     :  MIT+--+-- Maintainer  :  Phil Freeman <paf31@cantab.net>+-- Stability   :  experimental+-- Portability :+--+-- | Case binders+--+-----------------------------------------------------------------------------++{-# LANGUAGE DeriveDataTypeable #-}++module Language.PureScript.AST.Binders where++import qualified Data.Data as D++import Language.PureScript.AST.SourcePos+import Language.PureScript.Names++-- |+-- Data type for binders+--+data Binder+  -- |+  -- Wildcard binder+  --+  = NullBinder+  -- |+  -- A binder which matches a boolean literal+  --+  | BooleanBinder Bool+  -- |+  -- A binder which matches a string literal+  --+  | StringBinder String+  -- |+  -- A binder which matches a numeric literal+  --+  | NumberBinder (Either Integer Double)+  -- |+  -- A binder which binds an identifier+  --+  | VarBinder Ident+  -- |+  -- A binder which matches a data constructor+  --+  | ConstructorBinder (Qualified ProperName) [Binder]+  -- |+  -- A binder which matches a record and binds its properties+  --+  | ObjectBinder [(String, Binder)]+  -- |+  -- A binder which matches an array and binds its elements+  --+  | ArrayBinder [Binder]+  -- |+  -- A binder which matches an array and binds its head and tail+  --+  | ConsBinder Binder Binder+  -- |+  -- A binder which binds its input to an identifier+  --+  | NamedBinder Ident Binder+  -- |+  -- A binder with source position information+  --+  | PositionedBinder SourcePos Binder deriving (Show, D.Data, D.Typeable)++-- |+-- Collect all names introduced in binders in an expression+--+binderNames :: Binder -> [Ident]+binderNames = go []+  where+  go ns (VarBinder name) = name : ns+  go ns (ConstructorBinder _ bs) = foldl go ns bs+  go ns (ObjectBinder bs) = foldl go ns (map snd bs)+  go ns (ArrayBinder bs) = foldl go ns bs+  go ns (ConsBinder b1 b2) = go (go ns b1) b2+  go ns (NamedBinder name b) = go (name : ns) b+  go ns (PositionedBinder _ b) = go ns b+  go ns _ = ns
+ src/Language/PureScript/AST/Declarations.hs view
@@ -0,0 +1,362 @@+-----------------------------------------------------------------------------+--+-- Module      :  Language.PureScript.AST.Declarations+-- Copyright   :  (c) 2013-14 Phil Freeman, (c) 2014 Gary Burgess, and other contributors+-- License     :  MIT+--+-- Maintainer  :  Phil Freeman <paf31@cantab.net>+-- Stability   :  experimental+-- Portability :+--+-- | Data types for modules and declarations+--+-----------------------------------------------------------------------------++{-# LANGUAGE DeriveDataTypeable, ScopedTypeVariables #-}++module Language.PureScript.AST.Declarations where++import qualified Data.Data as D++import Language.PureScript.AST.Binders+import Language.PureScript.AST.Operators+import Language.PureScript.AST.SourcePos+import Language.PureScript.Types+import Language.PureScript.Names+import Language.PureScript.Kinds+import Language.PureScript.TypeClassDictionaries+import Language.PureScript.CodeGen.JS.AST+import Language.PureScript.Environment++-- |+-- A module declaration, consisting of a module name, a list of declarations, and a list of the+-- declarations that are explicitly exported. If the export list is Nothing, everything is exported.+--+data Module = Module ModuleName [Declaration] (Maybe [DeclarationRef]) deriving (Show, D.Data, D.Typeable)++-- |+-- An item in a list of explicit imports or exports+--+data DeclarationRef+  -- |+  -- A type constructor with data constructors+  --+  = TypeRef ProperName (Maybe [ProperName])+  -- |+  -- A value+  --+  | ValueRef Ident+  -- |+  -- A type class+  --+  | TypeClassRef ProperName+    -- |+  -- A type class instance, created during typeclass desugaring (name, class name, instance types)+  --+  | TypeInstanceRef Ident+  -- |+  -- A declaration reference with source position information+  --+  | PositionedDeclarationRef SourcePos DeclarationRef+  deriving (Show, D.Data, D.Typeable)++instance Eq DeclarationRef where+  (TypeRef name dctors)  == (TypeRef name' dctors') = name == name' && dctors == dctors'+  (ValueRef name)        == (ValueRef name')        = name == name'+  (TypeClassRef name)    == (TypeClassRef name')    = name == name'+  (TypeInstanceRef name) == (TypeInstanceRef name') = name == name'+  (PositionedDeclarationRef _ r) == r' = r == r'+  r == (PositionedDeclarationRef _ r') = r == r'+  _ == _ = False++-- |+-- The data type which specifies type of import declaration+--+data ImportDeclarationType+  -- |+  -- Unqualified import+  --+  = Unqualified+  -- |+  -- Qualified import with a list of references to import+  --+  | Qualifying [DeclarationRef]+  -- |+  -- Import with hiding clause with a list of references to hide+  --+  | Hiding [DeclarationRef]+  deriving (Show, D.Data, D.Typeable)++-- |+-- The data type of declarations+--+data Declaration+  -- |+  -- A data type declaration (data or newtype, name, arguments, data constructors)+  --+  = DataDeclaration DataDeclType ProperName [(String, Maybe Kind)] [(ProperName, [Type])]+  -- |+  -- A minimal mutually recursive set of data type declarations+  --+  | DataBindingGroupDeclaration [Declaration]+  -- |+  -- A type synonym declaration (name, arguments, type)+  --+  | TypeSynonymDeclaration ProperName [(String, Maybe Kind)] Type+  -- |+  -- A type declaration for a value (name, ty)+  --+  | TypeDeclaration Ident Type+  -- |+  -- A value declaration (name, top-level binders, optional guard, value)+  --+  | ValueDeclaration Ident NameKind [Binder] (Either [(Guard, Expr)] Expr)+  -- |+  -- A minimal mutually recursive set of value declarations+  --+  | BindingGroupDeclaration [(Ident, NameKind, Expr)]+  -- |+  -- A foreign import declaration (type, name, optional inline Javascript, type)+  --+  | ExternDeclaration ForeignImportType Ident (Maybe JS) Type+  -- |+  -- A data type foreign import (name, kind)+  --+  | ExternDataDeclaration ProperName Kind+  -- |+  -- A type class instance foreign import+  --+  | ExternInstanceDeclaration Ident [(Qualified ProperName, [Type])] (Qualified ProperName) [Type]+  -- |+  -- A fixity declaration (fixity data, operator name)+  --+  | FixityDeclaration Fixity String+  -- |+  -- A module import (module name, qualified/unqualified/hiding, optional "qualified as" name)+  --+  | ImportDeclaration ModuleName ImportDeclarationType (Maybe ModuleName)+  -- |+  -- A type class declaration (name, argument, implies, member declarations)+  --+  | TypeClassDeclaration ProperName [(String, Maybe Kind)] [(Qualified ProperName, [Type])] [Declaration]+  -- |+  -- A type instance declaration (name, dependencies, class name, instance types, member+  -- declarations)+  --+  | TypeInstanceDeclaration Ident [(Qualified ProperName, [Type])] (Qualified ProperName) [Type] [Declaration]+  -- |+  -- A declaration with source position information+  --+  | PositionedDeclaration SourcePos Declaration+  deriving (Show, D.Data, D.Typeable)++-- |+-- Test if a declaration is a value declaration+--+isValueDecl :: Declaration -> Bool+isValueDecl ValueDeclaration{} = True+isValueDecl (PositionedDeclaration _ d) = isValueDecl d+isValueDecl _ = False++-- |+-- Test if a declaration is a data type or type synonym declaration+--+isDataDecl :: Declaration -> Bool+isDataDecl DataDeclaration{} = True+isDataDecl TypeSynonymDeclaration{} = True+isDataDecl (PositionedDeclaration _ d) = isDataDecl d+isDataDecl _ = False++-- |+-- Test if a declaration is a module import+--+isImportDecl :: Declaration -> Bool+isImportDecl ImportDeclaration{} = True+isImportDecl (PositionedDeclaration _ d) = isImportDecl d+isImportDecl _ = False++-- |+-- Test if a declaration is a data type foreign import+--+isExternDataDecl :: Declaration -> Bool+isExternDataDecl ExternDataDeclaration{} = True+isExternDataDecl (PositionedDeclaration _ d) = isExternDataDecl d+isExternDataDecl _ = False++-- |+-- Test if a declaration is a type class instance foreign import+--+isExternInstanceDecl :: Declaration -> Bool+isExternInstanceDecl ExternInstanceDeclaration{} = True+isExternInstanceDecl (PositionedDeclaration _ d) = isExternInstanceDecl d+isExternInstanceDecl _ = False++-- |+-- Test if a declaration is a fixity declaration+--+isFixityDecl :: Declaration -> Bool+isFixityDecl FixityDeclaration{} = True+isFixityDecl (PositionedDeclaration _ d) = isFixityDecl d+isFixityDecl _ = False++-- |+-- Test if a declaration is a foreign import+--+isExternDecl :: Declaration -> Bool+isExternDecl ExternDeclaration{} = True+isExternDecl (PositionedDeclaration _ d) = isExternDecl d+isExternDecl _ = False++-- |+-- Test if a declaration is a type class or instance declaration+--+isTypeClassDeclaration :: Declaration -> Bool+isTypeClassDeclaration TypeClassDeclaration{} = True+isTypeClassDeclaration TypeInstanceDeclaration{} = True+isTypeClassDeclaration (PositionedDeclaration _ d) = isTypeClassDeclaration d+isTypeClassDeclaration _ = False++-- |+-- A guard is just a boolean-valued expression that appears alongside a set of binders+--+type Guard = Expr++-- |+-- Data type for expressions and terms+--+data Expr+  -- |+  -- A numeric literal+  --+  = NumericLiteral (Either Integer Double)+  -- |+  -- A string literal+  --+  | StringLiteral String+  -- |+  -- A boolean literal+  --+  | BooleanLiteral Bool+  -- |+  -- A prefix -, will be desugared+  --+  | UnaryMinus Expr+  -- |+  -- Binary operator application. During the rebracketing phase of desugaring, this data constructor+  -- will be removed.+  --+  | BinaryNoParens (Qualified Ident) Expr Expr+  -- |+  -- Explicit parentheses. During the rebracketing phase of desugaring, this data constructor+  -- will be removed.+  --+  | Parens Expr+  -- |+  -- An array literal+  --+  | ArrayLiteral [Expr]+  -- |+  -- An object literal+  --+  | ObjectLiteral [(String, Expr)]+  -- |+  -- An record property accessor expression+  --+  | Accessor String Expr+  -- |+  -- Partial record update+  --+  | ObjectUpdate Expr [(String, Expr)]+  -- |+  -- Function introduction+  --+  | Abs (Either Ident Binder) Expr+  -- |+  -- Function application+  --+  | App Expr Expr+  -- |+  -- Variable+  --+  | Var (Qualified Ident)+  -- |+  -- Conditional (if-then-else expression)+  --+  | IfThenElse Expr Expr Expr+  -- |+  -- A data constructor+  --+  | Constructor (Qualified ProperName)+  -- |+  -- A case expression. During the case expansion phase of desugaring, top-level binders will get+  -- desugared into case expressions, hence the need for guards and multiple binders per branch here.+  --+  | Case [Expr] [CaseAlternative]+  -- |+  -- A value with a type annotation+  --+  | TypedValue Bool Expr Type+  -- |+  -- A let binding+  --+  | Let [Declaration] Expr+  -- |+  -- A do-notation block+  --+  | Do [DoNotationElement]+  -- |+  -- An application of a typeclass dictionary constructor. The value should be+  -- an ObjectLiteral.+  --+  | TypeClassDictionaryConstructorApp (Qualified ProperName) Expr+  -- |+  -- A placeholder for a type class dictionary to be inserted later. At the end of type checking, these+  -- placeholders will be replaced with actual expressions representing type classes dictionaries which+  -- can be evaluated at runtime. The constructor arguments represent (in order): whether or not to look+  -- at superclass implementations when searching for a dictionary, the type class name and+  -- instance type, and the type class dictionaries in scope.+  --+  | TypeClassDictionary Bool (Qualified ProperName, [Type]) [TypeClassDictionaryInScope]+  -- |+  -- A placeholder for a superclass dictionary to be turned into a TypeClassDictionary during typechecking+  --+  | SuperClassDictionary (Qualified ProperName) [Type]+  -- |+  -- A value with source position information+  --+  | PositionedValue SourcePos Expr deriving (Show, D.Data, D.Typeable)++-- |+-- An alternative in a case statement+--+data CaseAlternative = CaseAlternative+  { -- |+    -- A collection of binders with which to match the inputs+    --+    caseAlternativeBinders :: [Binder]+    -- |+    -- The result expression or a collect of guarded expressions+    --+  , caseAlternativeResult :: Either [(Guard, Expr)] Expr+  } deriving (Show, D.Data, D.Typeable)++-- |+-- A statement in a do-notation block+--+data DoNotationElement+  -- |+  -- A monadic value without a binder+  --+  = DoNotationValue Expr+  -- |+  -- A monadic value with a binder+  --+  | DoNotationBind Binder Expr+  -- |+  -- A let statement, i.e. a pure value with a binder+  --+  | DoNotationLet [Declaration]+  -- |+  -- A do notation element with source position information+  --+  | PositionedDoNotationElement SourcePos DoNotationElement deriving (Show, D.Data, D.Typeable)
+ src/Language/PureScript/AST/Operators.hs view
@@ -0,0 +1,39 @@+-----------------------------------------------------------------------------+--+-- Module      :  Language.PureScript.AST.Operators+-- Copyright   :  (c) 2013-14 Phil Freeman, (c) 2014 Gary Burgess, and other contributors+-- License     :  MIT+--+-- Maintainer  :  Phil Freeman <paf31@cantab.net>+-- Stability   :  experimental+-- Portability :+--+-- | Operators fixity and associativity+--+-----------------------------------------------------------------------------++{-# LANGUAGE DeriveDataTypeable #-}++module Language.PureScript.AST.Operators where++import qualified Data.Data as D++-- |+-- A precedence level for an infix operator+--+type Precedence = Integer++-- |+-- Associativity for infix operators+--+data Associativity = Infixl | Infixr | Infix deriving (D.Data, D.Typeable)++instance Show Associativity where+  show Infixl = "infixl"+  show Infixr = "infixr"+  show Infix  = "infix"++-- |+-- Fixity data for infix operators+--+data Fixity = Fixity Associativity Precedence deriving (Show, D.Data, D.Typeable)
+ src/Language/PureScript/AST/SourcePos.hs view
@@ -0,0 +1,40 @@+-----------------------------------------------------------------------------+--+-- Module      :  Language.PureScript.AST.SourcePos+-- Copyright   :  (c) 2013-14 Phil Freeman, (c) 2014 Gary Burgess, and other contributors+-- License     :  MIT+--+-- Maintainer  :  Phil Freeman <paf31@cantab.net>+-- Stability   :  experimental+-- Portability :+--+-- | Source position information+--+-----------------------------------------------------------------------------++{-# LANGUAGE DeriveDataTypeable, ScopedTypeVariables #-}++module Language.PureScript.AST.SourcePos where++import qualified Data.Data as D++-- |+-- Source position information+--+data SourcePos = SourcePos+  { -- |+    -- Source name+    --+    sourceName :: String+    -- |+    -- Line number+    --+  , sourcePosLine :: Int+    -- |+    -- Column number+    --+  , sourcePosColumn :: Int+  } deriving (D.Data, D.Typeable)++instance Show SourcePos where+  show sp = sourceName sp ++ " line " ++ show (sourcePosLine sp) ++ ", column " ++ show (sourcePosColumn sp)
+ src/Language/PureScript/AST/Traversals.hs view
@@ -0,0 +1,383 @@+-----------------------------------------------------------------------------+--+-- Module      :  Language.PureScript.AST.Traversals+-- Copyright   :  (c) 2013-14 Phil Freeman, (c) 2014 Gary Burgess, and other contributors+-- License     :  MIT+--+-- Maintainer  :  Phil Freeman <paf31@cantab.net>+-- Stability   :  experimental+-- Portability :+--+-- | AST traversal helpers+--+-----------------------------------------------------------------------------++module Language.PureScript.AST.Traversals where++import Data.Monoid (Monoid(..), mconcat)++import Control.Applicative+import Control.Monad+import Control.Arrow ((***), (+++))++import Language.PureScript.AST.Binders+import Language.PureScript.AST.Declarations+import Language.PureScript.Types+import Language.PureScript.Traversals++everywhereOnValues :: (Declaration -> Declaration) ->+                      (Expr -> Expr) ->+                      (Binder -> Binder) ->+                      (Declaration -> Declaration, Expr -> Expr, Binder -> Binder)+everywhereOnValues f g h = (f', g', h')+  where+  f' :: Declaration -> Declaration+  f' (DataBindingGroupDeclaration ds) = f (DataBindingGroupDeclaration (map f' ds))+  f' (ValueDeclaration name nameKind bs val) = f (ValueDeclaration name nameKind (map h' bs) ((map (g' *** g') +++ g') val))+  f' (BindingGroupDeclaration ds) = f (BindingGroupDeclaration (map (\(name, nameKind, val) -> (name, nameKind, g' val)) ds))+  f' (TypeClassDeclaration name args implies ds) = f (TypeClassDeclaration name args implies (map f' ds))+  f' (TypeInstanceDeclaration name cs className args ds) = f (TypeInstanceDeclaration name cs className args (map f' ds))+  f' (PositionedDeclaration pos d) = f (PositionedDeclaration pos (f' d))+  f' other = f other++  g' :: Expr -> Expr+  g' (UnaryMinus v) = g (UnaryMinus (g' v))+  g' (BinaryNoParens op v1 v2) = g (BinaryNoParens op (g' v1) (g' v2))+  g' (Parens v) = g (Parens (g' v))+  g' (ArrayLiteral vs) = g (ArrayLiteral (map g' vs))+  g' (ObjectLiteral vs) = g (ObjectLiteral (map (fmap g') vs))+  g' (TypeClassDictionaryConstructorApp name v) = g (TypeClassDictionaryConstructorApp name (g' v))+  g' (Accessor prop v) = g (Accessor prop (g' v))+  g' (ObjectUpdate obj vs) = g (ObjectUpdate (g' obj) (map (fmap g') vs))+  g' (Abs name v) = g (Abs name (g' v))+  g' (App v1 v2) = g (App (g' v1) (g' v2))+  g' (IfThenElse v1 v2 v3) = g (IfThenElse (g' v1) (g' v2) (g' v3))+  g' (Case vs alts) = g (Case (map g' vs) (map handleCaseAlternative alts))+  g' (TypedValue check v ty) = g (TypedValue check (g' v) ty)+  g' (Let ds v) = g (Let (map f' ds) (g' v))+  g' (Do es) = g (Do (map handleDoNotationElement es))+  g' (PositionedValue pos v) = g (PositionedValue pos (g' v))+  g' other = g other++  h' :: Binder -> Binder+  h' (ConstructorBinder ctor bs) = h (ConstructorBinder ctor (map h' bs))+  h' (ObjectBinder bs) = h (ObjectBinder (map (fmap h') bs))+  h' (ArrayBinder bs) = h (ArrayBinder (map h' bs))+  h' (ConsBinder b1 b2) = h (ConsBinder (h' b1) (h' b2))+  h' (NamedBinder name b) = h (NamedBinder name (h' b))+  h' (PositionedBinder pos b) = h (PositionedBinder pos (h' b))+  h' other = h other++  handleCaseAlternative :: CaseAlternative -> CaseAlternative+  handleCaseAlternative ca =+    ca { caseAlternativeBinders = map h' (caseAlternativeBinders ca)+       , caseAlternativeResult = (map (g' *** g') +++ g') (caseAlternativeResult ca)+       }++  handleDoNotationElement :: DoNotationElement -> DoNotationElement+  handleDoNotationElement (DoNotationValue v) = DoNotationValue (g' v)+  handleDoNotationElement (DoNotationBind b v) = DoNotationBind (h' b) (g' v)+  handleDoNotationElement (DoNotationLet ds) = DoNotationLet (map f' ds)+  handleDoNotationElement (PositionedDoNotationElement pos e) = PositionedDoNotationElement pos (handleDoNotationElement e)+++everywhereOnValuesTopDownM :: (Functor m, Applicative m, Monad m) =>+  (Declaration -> m Declaration) ->+  (Expr -> m Expr) ->+  (Binder -> m Binder) ->+  (Declaration -> m Declaration, Expr -> m Expr, Binder -> m Binder)+everywhereOnValuesTopDownM f g h = (f' <=< f, g' <=< g, h' <=< h)+  where+  f' (DataBindingGroupDeclaration ds) = DataBindingGroupDeclaration <$> mapM (f' <=< f) ds+  f' (ValueDeclaration name nameKind bs val) = ValueDeclaration name nameKind <$> mapM (h' <=< h) bs <*> eitherM (mapM (pairM (g' <=< g) (g' <=< g))) (g' <=< g) val+  f' (BindingGroupDeclaration ds) = BindingGroupDeclaration <$> mapM (\(name, nameKind, val) -> (,,) name nameKind <$> (g val >>= g')) ds+  f' (TypeClassDeclaration name args implies ds) = TypeClassDeclaration name args implies <$> mapM (f' <=< f) ds+  f' (TypeInstanceDeclaration name cs className args ds) = TypeInstanceDeclaration name cs className args <$> mapM (f' <=< f) ds+  f' (PositionedDeclaration pos d) = PositionedDeclaration pos <$> (f d >>= f')+  f' other = f other++  g' (UnaryMinus v) = UnaryMinus <$> (g v >>= g')+  g' (BinaryNoParens op v1 v2) = BinaryNoParens op <$> (g v1 >>= g') <*> (g v2 >>= g')+  g' (Parens v) = Parens <$> (g v >>= g')+  g' (ArrayLiteral vs) = ArrayLiteral <$> mapM (g' <=< g) vs+  g' (ObjectLiteral vs) = ObjectLiteral <$> mapM (sndM (g' <=< g)) vs+  g' (TypeClassDictionaryConstructorApp name v) = TypeClassDictionaryConstructorApp name <$> (g v >>= g')+  g' (Accessor prop v) = Accessor prop <$> (g v >>= g')+  g' (ObjectUpdate obj vs) = ObjectUpdate <$> (g obj >>= g') <*> mapM (sndM (g' <=< g)) vs+  g' (Abs name v) = Abs name <$> (g v >>= g')+  g' (App v1 v2) = App <$> (g v1 >>= g') <*> (g v2 >>= g')+  g' (IfThenElse v1 v2 v3) = IfThenElse <$> (g v1 >>= g') <*> (g v2 >>= g') <*> (g v3 >>= g')+  g' (Case vs alts) = Case <$> mapM (g' <=< g) vs <*> mapM handleCaseAlternative alts+  g' (TypedValue check v ty) = TypedValue check <$> (g v >>= g') <*> pure ty+  g' (Let ds v) = Let <$> mapM (f' <=< f) ds <*> (g v >>= g')+  g' (Do es) = Do <$> mapM handleDoNotationElement es+  g' (PositionedValue pos v) = PositionedValue pos <$> (g v >>= g')+  g' other = g other++  h' (ConstructorBinder ctor bs) = ConstructorBinder ctor <$> mapM (h' <=< h) bs+  h' (ObjectBinder bs) = ObjectBinder <$> mapM (sndM (h' <=< h)) bs+  h' (ArrayBinder bs) = ArrayBinder <$> mapM (h' <=< h) bs+  h' (ConsBinder b1 b2) = ConsBinder <$> (h b1 >>= h') <*> (h b2 >>= h')+  h' (NamedBinder name b) = NamedBinder name <$> (h b >>= h')+  h' (PositionedBinder pos b) = PositionedBinder pos <$> (h b >>= h')+  h' other = h other++  handleCaseAlternative (CaseAlternative bs val) = CaseAlternative <$> mapM (h' <=< h) bs+                                                                   <*> eitherM (mapM (pairM (g' <=< g) (g' <=< g))) (g' <=< g) val++  handleDoNotationElement (DoNotationValue v) = DoNotationValue <$> (g' <=< g) v+  handleDoNotationElement (DoNotationBind b v) = DoNotationBind <$> (h' <=< h) b <*> (g' <=< g) v+  handleDoNotationElement (DoNotationLet ds) = DoNotationLet <$> mapM (f' <=< f) ds+  handleDoNotationElement (PositionedDoNotationElement pos e) = PositionedDoNotationElement pos <$> handleDoNotationElement e++everywhereOnValuesM :: (Functor m, Applicative m, Monad m) =>+  (Declaration -> m Declaration) ->+  (Expr -> m Expr) ->+  (Binder -> m Binder) ->+  (Declaration -> m Declaration, Expr -> m Expr, Binder -> m Binder)+everywhereOnValuesM f g h = (f' <=< f, g' <=< g, h' <=< h)+  where+  f' (DataBindingGroupDeclaration ds) = (DataBindingGroupDeclaration <$> mapM f' ds) >>= f+  f' (ValueDeclaration name nameKind bs val) = (ValueDeclaration name nameKind <$> mapM h' bs <*> eitherM (mapM (pairM g' g')) g' val) >>= f+  f' (BindingGroupDeclaration ds) = (BindingGroupDeclaration <$> mapM (\(name, nameKind, val) -> (,,) name nameKind <$> g' val) ds) >>= f+  f' (TypeClassDeclaration name args implies ds) = (TypeClassDeclaration name args implies <$> mapM f' ds) >>= f+  f' (TypeInstanceDeclaration name cs className args ds) = (TypeInstanceDeclaration name cs className args <$> mapM f' ds) >>= f+  f' (PositionedDeclaration pos d) = (PositionedDeclaration pos <$> f' d) >>= f+  f' other = f other++  g' (UnaryMinus v) = (UnaryMinus <$> g' v) >>= g+  g' (BinaryNoParens op v1 v2) = (BinaryNoParens op <$> g' v1 <*> g' v2) >>= g+  g' (Parens v) = (Parens <$> g' v) >>= g+  g' (ArrayLiteral vs) = (ArrayLiteral <$> mapM g' vs) >>= g+  g' (ObjectLiteral vs) = (ObjectLiteral <$> mapM (sndM g') vs) >>= g+  g' (TypeClassDictionaryConstructorApp name v) = (TypeClassDictionaryConstructorApp name <$> g' v) >>= g+  g' (Accessor prop v) = (Accessor prop <$> g' v) >>= g+  g' (ObjectUpdate obj vs) = (ObjectUpdate <$> g' obj <*> mapM (sndM g') vs) >>= g+  g' (Abs name v) = (Abs name <$> g' v) >>= g+  g' (App v1 v2) = (App <$> g' v1 <*> g' v2) >>= g+  g' (IfThenElse v1 v2 v3) = (IfThenElse <$> g' v1 <*> g' v2 <*> g' v3) >>= g+  g' (Case vs alts) = (Case <$> mapM g' vs <*> mapM handleCaseAlternative alts) >>= g+  g' (TypedValue check v ty) = (TypedValue check <$> g' v <*> pure ty) >>= g+  g' (Let ds v) = (Let <$> mapM f' ds <*> g' v) >>= g+  g' (Do es) = (Do <$> mapM handleDoNotationElement es) >>= g+  g' (PositionedValue pos v) = (PositionedValue pos <$> g' v) >>= g+  g' other = g other++  h' (ConstructorBinder ctor bs) = (ConstructorBinder ctor <$> mapM h' bs) >>= h+  h' (ObjectBinder bs) = (ObjectBinder <$> mapM (sndM h') bs) >>= h+  h' (ArrayBinder bs) = (ArrayBinder <$> mapM h' bs) >>= h+  h' (ConsBinder b1 b2) = (ConsBinder <$> h' b1 <*> h' b2) >>= h+  h' (NamedBinder name b) = (NamedBinder name <$> h' b) >>= h+  h' (PositionedBinder pos b) = (PositionedBinder pos <$> h' b) >>= h+  h' other = h other++  handleCaseAlternative (CaseAlternative bs val) = CaseAlternative <$> mapM h' bs+                                                                   <*> eitherM (mapM (pairM g' g')) g' val++  handleDoNotationElement (DoNotationValue v) = DoNotationValue <$> g' v+  handleDoNotationElement (DoNotationBind b v) = DoNotationBind <$> h' b <*> g' v+  handleDoNotationElement (DoNotationLet ds) = DoNotationLet <$> mapM f' ds+  handleDoNotationElement (PositionedDoNotationElement pos e) = PositionedDoNotationElement pos <$> handleDoNotationElement e++everythingOnValues :: (r -> r -> r) ->+                      (Declaration -> r) ->+                      (Expr -> r) ->+                      (Binder -> r) ->+                      (CaseAlternative -> r) ->+                      (DoNotationElement -> r) ->+                      (Declaration -> r, Expr -> r, Binder -> r, CaseAlternative -> r, DoNotationElement -> r)+everythingOnValues (<>) f g h i j = (f', g', h', i', j')+  where+  f' d@(DataBindingGroupDeclaration ds) = foldl (<>) (f d) (map f' ds)+  f' d@(ValueDeclaration _ _ bs (Right val)) = foldl (<>) (f d) (map h' bs) <> g' val+  f' d@(ValueDeclaration _ _ bs (Left gs)) = foldl (<>) (f d) (map h' bs ++ concatMap (\(grd, val) -> [g' grd, g' val]) gs)+  f' d@(BindingGroupDeclaration ds) = foldl (<>) (f d) (map (\(_, _, val) -> g' val) ds)+  f' d@(TypeClassDeclaration _ _ _ ds) = foldl (<>) (f d) (map f' ds)+  f' d@(TypeInstanceDeclaration _ _ _ _ ds) = foldl (<>) (f d) (map f' ds)+  f' d@(PositionedDeclaration _ d1) = f d <> f' d1+  f' d = f d++  g' v@(UnaryMinus v1) = g v <> g' v1+  g' v@(BinaryNoParens _ v1 v2) = g v <> g' v1 <> g' v2+  g' v@(Parens v1) = g v <> g' v1+  g' v@(ArrayLiteral vs) = foldl (<>) (g v) (map g' vs)+  g' v@(ObjectLiteral vs) = foldl (<>) (g v) (map (g' . snd) vs)+  g' v@(TypeClassDictionaryConstructorApp _ v1) = g v <> g' v1+  g' v@(Accessor _ v1) = g v <> g' v1+  g' v@(ObjectUpdate obj vs) = foldl (<>) (g v <> g' obj) (map (g' . snd) vs)+  g' v@(Abs _ v1) = g v <> g' v1+  g' v@(App v1 v2) = g v <> g' v1 <> g' v2+  g' v@(IfThenElse v1 v2 v3) = g v <> g' v1 <> g' v2 <> g' v3+  g' v@(Case vs alts) = foldl (<>) (foldl (<>) (g v) (map g' vs)) (map i' alts)+  g' v@(TypedValue _ v1 _) = g v <> g' v1+  g' v@(Let ds v1) = foldl (<>) (g v) (map f' ds) <> g' v1+  g' v@(Do es) = foldl (<>) (g v) (map j' es)+  g' v@(PositionedValue _ v1) = g v <> g' v1+  g' v = g v++  h' b@(ConstructorBinder _ bs) = foldl (<>) (h b) (map h' bs)+  h' b@(ObjectBinder bs) = foldl (<>) (h b) (map (h' . snd) bs)+  h' b@(ArrayBinder bs) = foldl (<>) (h b) (map h' bs)+  h' b@(ConsBinder b1 b2) = h b <> h' b1 <> h' b2+  h' b@(NamedBinder _ b1) = h b <> h' b1+  h' b@(PositionedBinder _ b1) = h b <> h' b1+  h' b = h b++  i' ca@(CaseAlternative bs (Right val)) = foldl (<>) (i ca) (map h' bs) <> g' val+  i' ca@(CaseAlternative bs (Left gs)) = foldl (<>) (i ca) (map h' bs ++ concatMap (\(grd, val) -> [g' grd, g' val]) gs)++  j' e@(DoNotationValue v) = j e <> g' v+  j' e@(DoNotationBind b v) = j e <> h' b <> g' v+  j' e@(DoNotationLet ds) = foldl (<>) (j e) (map f' ds)+  j' e@(PositionedDoNotationElement _ e1) = j e <> j' e1++everythingWithContextOnValues ::+  s ->+  r ->+  (r -> r -> r) ->+  (s -> Declaration       -> (s, r)) ->+  (s -> Expr              -> (s, r)) ->+  (s -> Binder            -> (s, r)) ->+  (s -> CaseAlternative   -> (s, r)) ->+  (s -> DoNotationElement -> (s, r)) ->+  ( Declaration       -> r+  , Expr              -> r+  , Binder            -> r+  , CaseAlternative   -> r+  , DoNotationElement -> r)+everythingWithContextOnValues s0 r0 (<>) f g h i j = (f'' s0, g'' s0, h'' s0, i'' s0, j'' s0)+  where+  f'' s d = let (s', r) = f s d in r <> f' s' d++  f' s (DataBindingGroupDeclaration ds) = foldl (<>) r0 (map (f'' s) ds)+  f' s (ValueDeclaration _ _ bs (Right val)) = foldl (<>) r0 (map (h'' s) bs) <> g'' s val+  f' s (ValueDeclaration _ _ bs (Left gs)) = foldl (<>) r0 (map (h'' s) bs ++ concatMap (\(grd, val) -> [g'' s grd, g'' s val]) gs)+  f' s (BindingGroupDeclaration ds) = foldl (<>) r0 (map (\(_, _, val) -> g'' s val) ds)+  f' s (TypeClassDeclaration _ _ _ ds) = foldl (<>) r0 (map (f'' s) ds)+  f' s (TypeInstanceDeclaration _ _ _ _ ds) = foldl (<>) r0 (map (f'' s) ds)+  f' s (PositionedDeclaration _ d1) = f'' s d1+  f' _ _ = r0++  g'' s v = let (s', r) = g s v in r <> g' s' v++  g' s (UnaryMinus v1) = g'' s v1+  g' s (BinaryNoParens _ v1 v2) = g'' s v1 <> g'' s v2+  g' s (Parens v1) = g'' s v1+  g' s (ArrayLiteral vs) = foldl (<>) r0 (map (g'' s) vs)+  g' s (ObjectLiteral vs) = foldl (<>) r0 (map (g'' s . snd) vs)+  g' s (TypeClassDictionaryConstructorApp _ v1) = g'' s v1+  g' s (Accessor _ v1) = g'' s v1+  g' s (ObjectUpdate obj vs) = foldl (<>) (g'' s obj) (map (g'' s . snd) vs)+  g' s (Abs _ v1) = g'' s v1+  g' s (App v1 v2) = g'' s v1 <> g'' s v2+  g' s (IfThenElse v1 v2 v3) = g'' s v1 <> g'' s v2 <> g'' s v3+  g' s (Case vs alts) = foldl (<>) (foldl (<>) r0 (map (g'' s) vs)) (map (i'' s) alts)+  g' s (TypedValue _ v1 _) = g'' s v1+  g' s (Let ds v1) = foldl (<>) r0 (map (f'' s) ds) <> g'' s v1+  g' s (Do es) = foldl (<>) r0 (map (j'' s) es)+  g' s (PositionedValue _ v1) = g'' s v1+  g' _ _ = r0++  h'' s b = let (s', r) = h s b in r <> h' s' b++  h' s (ConstructorBinder _ bs) = foldl (<>) r0 (map (h'' s) bs)+  h' s (ObjectBinder bs) = foldl (<>) r0 (map (h'' s . snd) bs)+  h' s (ArrayBinder bs) = foldl (<>) r0 (map (h'' s) bs)+  h' s (ConsBinder b1 b2) = h'' s b1 <> h'' s b2+  h' s (NamedBinder _ b1) = h'' s b1+  h' s (PositionedBinder _ b1) = h'' s b1+  h' _ _ = r0++  i'' s ca = let (s', r) = i s ca in r <> i' s' ca++  i' s (CaseAlternative bs (Right val)) = foldl (<>) r0 (map (h'' s) bs) <> g'' s val+  i' s (CaseAlternative bs (Left gs)) = foldl (<>) r0 (map (h'' s) bs ++ concatMap (\(grd, val) -> [g'' s grd, g'' s val]) gs)++  j'' s e = let (s', r) = j s e in r <> j' s' e++  j' s (DoNotationValue v) = g'' s v+  j' s (DoNotationBind b v) = h'' s b <> g'' s v+  j' s (DoNotationLet ds) = foldl (<>) r0 (map (f'' s) ds)+  j' s (PositionedDoNotationElement _ e1) = j'' s e1++everywhereWithContextOnValuesM :: (Functor m, Applicative m, Monad m) =>+  s ->+  (s -> Declaration       -> m (s, Declaration)) ->+  (s -> Expr              -> m (s, Expr)) ->+  (s -> Binder            -> m (s, Binder)) ->+  (s -> CaseAlternative   -> m (s, CaseAlternative)) ->+  (s -> DoNotationElement -> m (s, DoNotationElement)) ->+  ( Declaration       -> m Declaration+  , Expr              -> m Expr+  , Binder            -> m Binder+  , CaseAlternative   -> m CaseAlternative+  , DoNotationElement -> m DoNotationElement)+everywhereWithContextOnValuesM s0 f g h i j = (f'' s0, g'' s0, h'' s0, i'' s0, j'' s0)+  where+  f'' s = uncurry f' <=< f s++  f' s (DataBindingGroupDeclaration ds) = DataBindingGroupDeclaration <$> mapM (f'' s) ds+  f' s (ValueDeclaration name nameKind bs val) = ValueDeclaration name nameKind <$> mapM (h'' s) bs <*> eitherM (mapM (pairM (g'' s) (g'' s))) (g'' s) val+  f' s (BindingGroupDeclaration ds) = BindingGroupDeclaration <$> mapM (thirdM (g'' s)) ds+  f' s (TypeClassDeclaration name args implies ds) = TypeClassDeclaration name args implies <$> mapM (f'' s) ds+  f' s (TypeInstanceDeclaration name cs className args ds) = TypeInstanceDeclaration name cs className args <$> mapM (f'' s) ds+  f' s (PositionedDeclaration pos d1) = PositionedDeclaration pos <$> f'' s d1+  f' _ other = return other++  g'' s = uncurry g' <=< g s++  g' s (UnaryMinus v) = UnaryMinus <$> g'' s v+  g' s (BinaryNoParens op v1 v2) = BinaryNoParens op <$> g'' s v1 <*> g'' s v2+  g' s (Parens v) = Parens <$> g'' s v+  g' s (ArrayLiteral vs) = ArrayLiteral <$> mapM (g'' s) vs+  g' s (ObjectLiteral vs) = ObjectLiteral <$> mapM (sndM (g'' s)) vs+  g' s (TypeClassDictionaryConstructorApp name v) = TypeClassDictionaryConstructorApp name <$> g'' s v+  g' s (Accessor prop v) = Accessor prop <$> g'' s v+  g' s (ObjectUpdate obj vs) = ObjectUpdate <$> g'' s obj <*> mapM (sndM (g'' s)) vs+  g' s (Abs name v) = Abs name <$> g'' s v+  g' s (App v1 v2) = App <$> g'' s v1 <*> g'' s v2+  g' s (IfThenElse v1 v2 v3) = IfThenElse <$> g'' s v1 <*> g'' s v2 <*> g'' s v3+  g' s (Case vs alts) = Case <$> mapM (g'' s) vs <*> mapM (i'' s) alts+  g' s (TypedValue check v ty) = TypedValue check <$> g'' s v <*> pure ty+  g' s (Let ds v) = Let <$> mapM (f'' s) ds <*> g'' s v+  g' s (Do es) = Do <$> mapM (j'' s) es+  g' s (PositionedValue pos v) = PositionedValue pos <$> g'' s v+  g' _ other = return other++  h'' s = uncurry h' <=< h s++  h' s (ConstructorBinder ctor bs) = ConstructorBinder ctor <$> mapM (h'' s) bs+  h' s (ObjectBinder bs) = ObjectBinder <$> mapM (sndM (h'' s)) bs+  h' s (ArrayBinder bs) = ArrayBinder <$> mapM (h'' s) bs+  h' s (ConsBinder b1 b2) = ConsBinder <$> h'' s b1 <*> h'' s b2+  h' s (NamedBinder name b) = NamedBinder name <$> h'' s b+  h' s (PositionedBinder pos b) = PositionedBinder pos <$> h'' s b+  h' _ other = return other++  i'' s = uncurry i' <=< i s++  i' s (CaseAlternative bs val) = CaseAlternative <$> mapM (h'' s) bs <*> eitherM (mapM (pairM (g'' s) (g'' s))) (g'' s) val++  j'' s = uncurry j' <=< j s++  j' s (DoNotationValue v) = DoNotationValue <$> g'' s v+  j' s (DoNotationBind b v) = DoNotationBind <$> h'' s b <*> g'' s v+  j' s (DoNotationLet ds) = DoNotationLet <$> mapM (f'' s) ds+  j' s (PositionedDoNotationElement pos e1) = PositionedDoNotationElement pos <$> j'' s e1++accumTypes :: (Monoid r) => (Type -> r) -> (Declaration -> r, Expr -> r, Binder -> r, CaseAlternative -> r, DoNotationElement -> r)+accumTypes f = everythingOnValues mappend forDecls forValues (const mempty) (const mempty) (const mempty)+  where+  forDecls (DataDeclaration _ _ _ dctors) = mconcat (concatMap (map f . snd) dctors)+  forDecls (ExternDeclaration _ _ _ ty) = f ty+  forDecls (ExternInstanceDeclaration _ cs _ tys) = mconcat (concatMap (map f . snd) cs) `mappend` mconcat (map f tys)+  forDecls (TypeClassDeclaration _ _ implies _) = mconcat (concatMap (map f . snd) implies)+  forDecls (TypeInstanceDeclaration _ cs _ tys _) = mconcat (concatMap (map f . snd) cs) `mappend` mconcat (map f tys)+  forDecls (TypeSynonymDeclaration _ _ ty) = f ty+  forDecls (TypeDeclaration _ ty) = f ty+  forDecls _ = mempty++  forValues (TypeClassDictionary _ (_, cs) _) = mconcat (map f cs)+  forValues (SuperClassDictionary _ tys) = mconcat (map f tys)+  forValues (TypedValue _ _ ty) = f ty+  forValues _ = mempty
src/Language/PureScript/CodeGen/Externs.hs view
@@ -26,7 +26,7 @@  import Language.PureScript.CodeGen.Common import Language.PureScript.TypeClassDictionaries-import Language.PureScript.Declarations+import Language.PureScript.AST import Language.PureScript.Pretty import Language.PureScript.Names import Language.PureScript.Kinds@@ -87,8 +87,8 @@       case Qualified (Just moduleName) className `M.lookup` typeClasses env of         Nothing -> error $ show className ++ " has no type class definition in exportToPs"         Just (args, members, implies) -> do-          let impliesString = if null implies -                              then "" +          let impliesString = if null implies+                              then ""                               else "(" ++ intercalate ", " (map (\(pn, tys') -> show pn ++ " " ++ unwords (map prettyPrintTypeAtom tys')) implies) ++ ") <= "               typeName = prettyPrintType $ foldl TypeApp (TypeConstructor (Qualified Nothing className)) (map toTypeVar args)           tell ["class " ++ impliesString ++ typeName ++ " where"]
src/Language/PureScript/CodeGen/JS.hs view
@@ -33,7 +33,7 @@ import Control.Arrow (second)  import Language.PureScript.Names-import Language.PureScript.Declarations+import Language.PureScript.AST import Language.PureScript.Options import Language.PureScript.CodeGen.JS.AST as AST import Language.PureScript.Optimizer@@ -93,7 +93,7 @@ -- Generate code in the simplified Javascript intermediate representation for a declaration -- declToJs :: (Functor m, Applicative m, Monad m) => Options mode -> ModuleName -> Declaration -> Environment -> SupplyT m (Maybe [JS])-declToJs opts mp (ValueDeclaration ident _ _ _ val) e = do+declToJs opts mp (ValueDeclaration ident _ _ (Right val)) e = do   js <- valueToJs opts mp e val   return $ Just [JSVariableIntroduction (identToJs ident) (Just js)] declToJs opts mp (BindingGroupDeclaration vals) e = do@@ -280,21 +280,25 @@ bindersToJs opts m e binders vals = do   valNames <- replicateM (length vals) freshName   let assignments = zipWith JSVariableIntroduction valNames (map Just vals)-  jss <- forM binders $ \(CaseAlternative bs grd result) -> do-    ret <- valueToJs opts m e result-    go valNames [JSReturn ret] bs grd+  jss <- forM binders $ \(CaseAlternative bs result) -> do+    ret <- guardsToJs result+    go valNames ret bs   return $ JSApp (JSFunction Nothing [] (JSBlock (assignments ++ concat jss ++ [JSThrow $ JSUnary JSNew $ JSApp (JSVar "Error") $ [JSStringLiteral "Failed pattern match"]])))                  []   where-    go :: (Functor m, Applicative m, Monad m) => [String] -> [JS] -> [Binder] -> Maybe Guard -> SupplyT m [JS]-    go _ done [] Nothing = return done-    go _ done [] (Just cond) = do-      cond' <- valueToJs opts m e cond-      return [JSIfElse cond' (JSBlock done) Nothing]-    go (v:vs) done' (b:bs) grd = do-      done'' <- go vs done' bs grd+    go :: (Functor m, Applicative m, Monad m) => [String] -> [JS] -> [Binder] -> SupplyT m [JS]+    go _ done [] = return done+    go (v:vs) done' (b:bs) = do+      done'' <- go vs done' bs       binderToJs m e v done'' b-    go _ _ _ _ = error "Invalid arguments to bindersToJs"+    go _ _ _ = error "Invalid arguments to bindersToJs"++    guardsToJs :: (Functor m, Applicative m, Monad m) => Either [(Guard, Expr)] Expr -> SupplyT m [JS]+    guardsToJs (Left gs) = forM gs $ \(cond, val) -> do+      cond' <- valueToJs opts m e cond+      done  <- valueToJs opts m e val+      return $ JSIfElse cond' (JSBlock [JSReturn done]) Nothing+    guardsToJs (Right v) = return . JSReturn <$> valueToJs opts m e v  -- | -- Generate code in the simplified Javascript intermediate representation for a pattern match
src/Language/PureScript/Constants.hs view
@@ -153,6 +153,9 @@ runFn :: String runFn = "runFn" +unit :: String+unit = "unit"+ -- Prim values  undefined :: String
src/Language/PureScript/DeadCodeElimination.hs view
@@ -21,7 +21,7 @@ import Data.Maybe (mapMaybe)  import Language.PureScript.Names-import Language.PureScript.Declarations+import Language.PureScript.AST  -- | -- Eliminate all declarations which are not a transitive dependency of the entry point module@@ -46,7 +46,7 @@   filterExport _ _ = Nothing    valueExists :: Ident -> Declaration -> Bool-  valueExists name (ValueDeclaration name' _ _ _ _) = name == name'+  valueExists name (ValueDeclaration name' _ _ _) = name == name'   valueExists name (ExternDeclaration _ name' _ _) = name == name'   valueExists name (BindingGroupDeclaration decls) = any (\(name', _, _) -> name == name') decls   valueExists name (PositionedDeclaration _ d) = valueExists name d@@ -65,7 +65,7 @@ declarationsByModule (Module moduleName ds _) = concatMap go ds   where   go :: Declaration -> [(Key, [Key])]-  go d@(ValueDeclaration name _ _ _ _) = [((moduleName, Left name), dependencies moduleName d)]+  go d@(ValueDeclaration name _ _ _) = [((moduleName, Left name), dependencies moduleName d)]   go (DataDeclaration _ _ _ dctors) = map (\(name, _) -> ((moduleName, Right name), [])) dctors   go (ExternDeclaration _ name _ _) = [((moduleName, Left name), [])]   go d@(BindingGroupDeclaration names') = map (\(name, _, _) -> ((moduleName, Left name), dependencies moduleName d)) names'@@ -88,7 +88,7 @@   values _ = []  isUsed :: ModuleName -> Graph -> (Key -> Maybe Vertex) -> [Vertex] -> Declaration -> Bool-isUsed moduleName graph vertexFor entryPointVertices (ValueDeclaration name _ _ _ _) =+isUsed moduleName graph vertexFor entryPointVertices (ValueDeclaration name _ _ _) =   let Just v' = vertexFor (moduleName, Left name)   in any (\v -> path graph v v') entryPointVertices isUsed moduleName graph vertexFor entryPointVertices (FixityDeclaration _ name) =
− src/Language/PureScript/Declarations.hs
@@ -1,849 +0,0 @@------------------------------------------------------------------------------------ Module      :  Language.PureScript.Declarations--- Copyright   :  (c) Phil Freeman 2013--- License     :  MIT------ Maintainer  :  Phil Freeman <paf31@cantab.net>--- Stability   :  experimental--- Portability :------ | Data types for modules and declarations-----------------------------------------------------------------------------------{-# LANGUAGE DeriveDataTypeable, ScopedTypeVariables #-}--module Language.PureScript.Declarations where--import Data.Monoid (Monoid(..), mconcat)--import qualified Data.Data as D--import Control.Applicative-import Control.Monad--import Language.PureScript.Types-import Language.PureScript.Names-import Language.PureScript.Kinds-import Language.PureScript.TypeClassDictionaries-import Language.PureScript.CodeGen.JS.AST-import Language.PureScript.Environment-import Language.PureScript.Traversals---- |--- A precedence level for an infix operator----type Precedence = Integer---- |--- Associativity for infix operators----data Associativity = Infixl | Infixr | Infix deriving (D.Data, D.Typeable)--instance Show Associativity where-  show Infixl = "infixl"-  show Infixr = "infixr"-  show Infix  = "infix"---- |--- Source position information----data SourcePos = SourcePos-  { -- |-    -- Source name-    ---    sourceName :: String-    -- |-    -- Line number-    ---  , sourcePosLine :: Int-    -- |-    -- Column number-    ---  , sourcePosColumn :: Int-  } deriving (D.Data, D.Typeable)--instance Show SourcePos where-  show sp = (sourceName sp) ++ " line " ++ show (sourcePosLine sp) ++ ", column " ++ show (sourcePosColumn sp)---- |--- Fixity data for infix operators----data Fixity = Fixity Associativity Precedence deriving (Show, D.Data, D.Typeable)---- |--- A module declaration, consisting of a module name, a list of declarations, and a list of the--- declarations that are explicitly exported. If the export list is Nothing, everything is exported.----data Module = Module ModuleName [Declaration] (Maybe [DeclarationRef]) deriving (Show, D.Data, D.Typeable)---- |--- An item in a list of explicit imports or exports----data DeclarationRef-  -- |-  -- A type constructor with data constructors-  ---  = TypeRef ProperName (Maybe [ProperName])-  -- |-  -- A value-  ---  | ValueRef Ident-  -- |-  -- A type class-  ---  | TypeClassRef ProperName-    -- |-  -- A type class instance, created during typeclass desugaring (name, class name, instance types)-  ---  | TypeInstanceRef Ident-  -- |-  -- A declaration reference with source position information-  ---  | PositionedDeclarationRef SourcePos DeclarationRef-  deriving (Show, D.Data, D.Typeable)--instance Eq DeclarationRef where-  (TypeRef name dctors)  == (TypeRef name' dctors') = name == name' && dctors == dctors'-  (ValueRef name)        == (ValueRef name')        = name == name'-  (TypeClassRef name)    == (TypeClassRef name')    = name == name'-  (TypeInstanceRef name) == (TypeInstanceRef name') = name == name'-  (PositionedDeclarationRef _ r) == r' = r == r'-  r == (PositionedDeclarationRef _ r') = r == r'-  _ == _ = False---- |--- The data type which specifies type of import declaration----data ImportDeclarationType-  -- |-  -- Unqualified import-  ---  = Unqualified-  -- |-  -- Qualified import with a list of references to import-  ---  | Qualifying [DeclarationRef]-  -- |-  -- Import with hiding clause with a list of references to hide-  ---  | Hiding [DeclarationRef]-  deriving (Show, D.Data, D.Typeable)---- |--- The data type of declarations----data Declaration-  -- |-  -- A data type declaration (data or newtype, name, arguments, data constructors)-  ---  = DataDeclaration DataDeclType ProperName [(String, Maybe Kind)] [(ProperName, [Type])]-  -- |-  -- A minimal mutually recursive set of data type declarations-  ---  | DataBindingGroupDeclaration [Declaration]-  -- |-  -- A type synonym declaration (name, arguments, type)-  ---  | TypeSynonymDeclaration ProperName [(String, Maybe Kind)] Type-  -- |-  -- A type declaration for a value (name, ty)-  ---  | TypeDeclaration Ident Type-  -- |-  -- A value declaration (name, top-level binders, optional guard, value)-  ---  | ValueDeclaration Ident NameKind [Binder] (Maybe Guard) Expr-  -- |-  -- A minimal mutually recursive set of value declarations-  ---  | BindingGroupDeclaration [(Ident, NameKind, Expr)]-  -- |-  -- A foreign import declaration (type, name, optional inline Javascript, type)-  ---  | ExternDeclaration ForeignImportType Ident (Maybe JS) Type-  -- |-  -- A data type foreign import (name, kind)-  ---  | ExternDataDeclaration ProperName Kind-  -- |-  -- A type class instance foreign import-  ---  | ExternInstanceDeclaration Ident [(Qualified ProperName, [Type])] (Qualified ProperName) [Type]-  -- |-  -- A fixity declaration (fixity data, operator name)-  ---  | FixityDeclaration Fixity String-  -- |-  -- A module import (module name, optional set of identifiers to import,-  -- optional set of identifiers to hide, optional "qualified as" name)-  ---  | ImportDeclaration ModuleName ImportDeclarationType (Maybe ModuleName)-  -- |-  -- A type class declaration (name, argument, implies, member declarations)-  ---  | TypeClassDeclaration ProperName [(String, Maybe Kind)] [(Qualified ProperName, [Type])] [Declaration]-  -- |-  -- A type instance declaration (name, dependencies, class name, instance types, member-  -- declarations)-  ---  | TypeInstanceDeclaration Ident [(Qualified ProperName, [Type])] (Qualified ProperName) [Type] [Declaration]-  -- |-  -- A declaration with source position information-  ---  | PositionedDeclaration SourcePos Declaration-  deriving (Show, D.Data, D.Typeable)---- |--- Test if a declaration is a value declaration----isValueDecl :: Declaration -> Bool-isValueDecl ValueDeclaration{} = True-isValueDecl (PositionedDeclaration _ d) = isValueDecl d-isValueDecl _ = False---- |--- Test if a declaration is a data type or type synonym declaration----isDataDecl :: Declaration -> Bool-isDataDecl DataDeclaration{} = True-isDataDecl TypeSynonymDeclaration{} = True-isDataDecl (PositionedDeclaration _ d) = isDataDecl d-isDataDecl _ = False---- |--- Test if a declaration is a module import----isImportDecl :: Declaration -> Bool-isImportDecl ImportDeclaration{} = True-isImportDecl (PositionedDeclaration _ d) = isImportDecl d-isImportDecl _ = False---- |--- Test if a declaration is a data type foreign import----isExternDataDecl :: Declaration -> Bool-isExternDataDecl ExternDataDeclaration{} = True-isExternDataDecl (PositionedDeclaration _ d) = isExternDataDecl d-isExternDataDecl _ = False---- |--- Test if a declaration is a type class instance foreign import----isExternInstanceDecl :: Declaration -> Bool-isExternInstanceDecl ExternInstanceDeclaration{} = True-isExternInstanceDecl (PositionedDeclaration _ d) = isExternInstanceDecl d-isExternInstanceDecl _ = False---- |--- Test if a declaration is a fixity declaration----isFixityDecl :: Declaration -> Bool-isFixityDecl FixityDeclaration{} = True-isFixityDecl (PositionedDeclaration _ d) = isFixityDecl d-isFixityDecl _ = False---- |--- Test if a declaration is a foreign import----isExternDecl :: Declaration -> Bool-isExternDecl ExternDeclaration{} = True-isExternDecl (PositionedDeclaration _ d) = isExternDecl d-isExternDecl _ = False---- |--- Test if a declaration is a type class or instance declaration----isTypeClassDeclaration :: Declaration -> Bool-isTypeClassDeclaration TypeClassDeclaration{} = True-isTypeClassDeclaration TypeInstanceDeclaration{} = True-isTypeClassDeclaration (PositionedDeclaration _ d) = isTypeClassDeclaration d-isTypeClassDeclaration _ = False---- |--- A guard is just a boolean-valued expression that appears alongside a set of binders----type Guard = Expr---- |--- Data type for expressions and terms----data Expr-  -- |-  -- A numeric literal-  ---  = NumericLiteral (Either Integer Double)-  -- |-  -- A string literal-  ---  | StringLiteral String-  -- |-  -- A boolean literal-  ---  | BooleanLiteral Bool-  -- |-  -- A prefix -, will be desugared-  ---  | UnaryMinus Expr-  -- |-  -- Binary operator application. During the rebracketing phase of desugaring, this data constructor-  -- will be removed.-  ---  | BinaryNoParens (Qualified Ident) Expr Expr-  -- |-  -- Explicit parentheses. During the rebracketing phase of desugaring, this data constructor-  -- will be removed.-  ---  | Parens Expr-  -- |-  -- An array literal-  ---  | ArrayLiteral [Expr]-  -- |-  -- An object literal-  ---  | ObjectLiteral [(String, Expr)]-  -- |-  -- An record property accessor expression-  ---  | Accessor String Expr-  -- |-  -- Partial record update-  ---  | ObjectUpdate Expr [(String, Expr)]-  -- |-  -- Function introduction-  ---  | Abs (Either Ident Binder) Expr-  -- |-  -- Function application-  ---  | App Expr Expr-  -- |-  -- Variable-  ---  | Var (Qualified Ident)-  -- |-  -- Conditional (if-then-else expression)-  ---  | IfThenElse Expr Expr Expr-  -- |-  -- A data constructor-  ---  | Constructor (Qualified ProperName)-  -- |-  -- A case expression. During the case expansion phase of desugaring, top-level binders will get-  -- desugared into case expressions, hence the need for guards and multiple binders per branch here.-  ---  | Case [Expr] [CaseAlternative]-  -- |-  -- A value with a type annotation-  ---  | TypedValue Bool Expr Type-  -- |-  -- A let binding-  ---  | Let [Declaration] Expr-  -- |-  -- A do-notation block-  ---  | Do [DoNotationElement]-  -- |-  -- An application of a typeclass dictionary constructor. The value should be-  -- an ObjectLiteral.-  ---  | TypeClassDictionaryConstructorApp (Qualified ProperName) Expr-  -- |-  -- A placeholder for a type class dictionary to be inserted later. At the end of type checking, these-  -- placeholders will be replaced with actual expressions representing type classes dictionaries which-  -- can be evaluated at runtime. The constructor arguments represent (in order): whether or not to look-  -- at superclass implementations when searching for a dictionary, the type class name and-  -- instance type, and the type class dictionaries in scope.-  ---  | TypeClassDictionary Bool (Qualified ProperName, [Type]) [TypeClassDictionaryInScope]-  -- |-  -- A placeholder for a superclass dictionary to be turned into a TypeClassDictionary during typechecking-  ---  | SuperClassDictionary (Qualified ProperName) [Type]-  -- |-  -- A value with source position information-  ---  | PositionedValue SourcePos Expr deriving (Show, D.Data, D.Typeable)---- |--- An alternative in a case statement----data CaseAlternative = CaseAlternative-  { -- |-    -- A collection of binders with which to match the inputs-    ---    caseAlternativeBinders :: [Binder]-    -- |-    -- An optional guard-    ---  , caseAlternativeGuard :: Maybe Guard-    -- |-    -- The result expression-    ---  , caseAlternativeResult :: Expr-  } deriving (Show, D.Data, D.Typeable)---- |--- Find the original dictionary which a type class dictionary in scope refers to----canonicalizeDictionary :: TypeClassDictionaryInScope -> Qualified Ident-canonicalizeDictionary (TypeClassDictionaryInScope { tcdType = TCDRegular, tcdName = nm }) = nm-canonicalizeDictionary (TypeClassDictionaryInScope { tcdType = TCDAlias nm }) = nm---- |--- A statement in a do-notation block----data DoNotationElement-  -- |-  -- A monadic value without a binder-  ---  = DoNotationValue Expr-  -- |-  -- A monadic value with a binder-  ---  | DoNotationBind Binder Expr-  -- |-  -- A let statement, i.e. a pure value with a binder-  ---  | DoNotationLet [Declaration]-  -- |-  -- A do notation element with source position information-  ---  | PositionedDoNotationElement SourcePos DoNotationElement deriving (Show, D.Data, D.Typeable)---- |--- Data type for binders----data Binder-  -- |-  -- Wildcard binder-  ---  = NullBinder-  -- |-  -- A binder which matches a boolean literal-  ---  | BooleanBinder Bool-  -- |-  -- A binder which matches a string literal-  ---  | StringBinder String-  -- |-  -- A binder which matches a numeric literal-  ---  | NumberBinder (Either Integer Double)-  -- |-  -- A binder which binds an identifier-  ---  | VarBinder Ident-  -- |-  -- A binder which matches a data constructor-  ---  | ConstructorBinder (Qualified ProperName) [Binder]-  -- |-  -- A binder which matches a record and binds its properties-  ---  | ObjectBinder [(String, Binder)]-  -- |-  -- A binder which matches an array and binds its elements-  ---  | ArrayBinder [Binder]-  -- |-  -- A binder which matches an array and binds its head and tail-  ---  | ConsBinder Binder Binder-  -- |-  -- A binder which binds its input to an identifier-  ---  | NamedBinder Ident Binder-  -- |-  -- A binder with source position information-  ---  | PositionedBinder SourcePos Binder deriving (Show, D.Data, D.Typeable)---- |--- Collect all names introduced in binders in an expression----binderNames :: Binder -> [Ident]-binderNames = go []-  where-  go ns (VarBinder name) = name : ns-  go ns (ConstructorBinder _ bs) = foldl go ns bs-  go ns (ObjectBinder bs) = foldl go ns (map snd bs)-  go ns (ArrayBinder bs) = foldl go ns bs-  go ns (ConsBinder b1 b2) = go (go ns b1) b2-  go ns (NamedBinder name b) = go (name : ns) b-  go ns (PositionedBinder _ b) = go ns b-  go ns _ = ns------- Traversals-----everywhereOnValues :: (Declaration -> Declaration) ->-                      (Expr -> Expr) ->-                      (Binder -> Binder) ->-                      (Declaration -> Declaration, Expr -> Expr, Binder -> Binder)-everywhereOnValues f g h = (f', g', h')-  where-  f' :: Declaration -> Declaration-  f' (DataBindingGroupDeclaration ds) = f (DataBindingGroupDeclaration (map f' ds))-  f' (ValueDeclaration name nameKind bs grd val) = f (ValueDeclaration name nameKind (map h' bs) (fmap g' grd) (g' val))-  f' (BindingGroupDeclaration ds) = f (BindingGroupDeclaration (map (\(name, nameKind, val) -> (name, nameKind, g' val)) ds))-  f' (TypeClassDeclaration name args implies ds) = f (TypeClassDeclaration name args implies (map f' ds))-  f' (TypeInstanceDeclaration name cs className args ds) = f (TypeInstanceDeclaration name cs className args (map f' ds))-  f' (PositionedDeclaration pos d) = f (PositionedDeclaration pos (f' d))-  f' other = f other--  g' :: Expr -> Expr-  g' (UnaryMinus v) = g (UnaryMinus (g' v))-  g' (BinaryNoParens op v1 v2) = g (BinaryNoParens op (g' v1) (g' v2))-  g' (Parens v) = g (Parens (g' v))-  g' (ArrayLiteral vs) = g (ArrayLiteral (map g' vs))-  g' (ObjectLiteral vs) = g (ObjectLiteral (map (fmap g') vs))-  g' (TypeClassDictionaryConstructorApp name v) = g (TypeClassDictionaryConstructorApp name (g' v))-  g' (Accessor prop v) = g (Accessor prop (g' v))-  g' (ObjectUpdate obj vs) = g (ObjectUpdate (g' obj) (map (fmap g') vs))-  g' (Abs name v) = g (Abs name (g' v))-  g' (App v1 v2) = g (App (g' v1) (g' v2))-  g' (IfThenElse v1 v2 v3) = g (IfThenElse (g' v1) (g' v2) (g' v3))-  g' (Case vs alts) = g (Case (map g' vs) (map handleCaseAlternative alts))-  g' (TypedValue check v ty) = g (TypedValue check (g' v) ty)-  g' (Let ds v) = g (Let (map f' ds) (g' v))-  g' (Do es) = g (Do (map handleDoNotationElement es))-  g' (PositionedValue pos v) = g (PositionedValue pos (g' v))-  g' other = g other--  h' :: Binder -> Binder-  h' (ConstructorBinder ctor bs) = h (ConstructorBinder ctor (map h' bs))-  h' (ObjectBinder bs) = h (ObjectBinder (map (fmap h') bs))-  h' (ArrayBinder bs) = h (ArrayBinder (map h' bs))-  h' (ConsBinder b1 b2) = h (ConsBinder (h' b1) (h' b2))-  h' (NamedBinder name b) = h (NamedBinder name (h' b))-  h' (PositionedBinder pos b) = h (PositionedBinder pos (h' b))-  h' other = h other--  handleCaseAlternative :: CaseAlternative -> CaseAlternative-  handleCaseAlternative ca =-    ca { caseAlternativeBinders = map h' (caseAlternativeBinders ca)-       , caseAlternativeGuard = fmap g' (caseAlternativeGuard ca)-       , caseAlternativeResult = g' (caseAlternativeResult ca)-       }--  handleDoNotationElement :: DoNotationElement -> DoNotationElement-  handleDoNotationElement (DoNotationValue v) = DoNotationValue (g' v)-  handleDoNotationElement (DoNotationBind b v) = DoNotationBind (h' b) (g' v)-  handleDoNotationElement (DoNotationLet ds) = DoNotationLet (map f' ds)-  handleDoNotationElement (PositionedDoNotationElement pos e) = PositionedDoNotationElement pos (handleDoNotationElement e)---everywhereOnValuesTopDownM :: (Functor m, Applicative m, Monad m) =>-  (Declaration -> m Declaration) ->-  (Expr -> m Expr) ->-  (Binder -> m Binder) ->-  (Declaration -> m Declaration, Expr -> m Expr, Binder -> m Binder)-everywhereOnValuesTopDownM f g h = (f' <=< f, g' <=< g, h' <=< h)-  where-  f' (DataBindingGroupDeclaration ds) = DataBindingGroupDeclaration <$> mapM (f' <=< f) ds-  f' (ValueDeclaration name nameKind bs grd val) = ValueDeclaration name nameKind <$> mapM (h' <=< h) bs <*> maybeM (g' <=< g) grd <*> (g val >>= g')-  f' (BindingGroupDeclaration ds) = BindingGroupDeclaration <$> mapM (\(name, nameKind, val) -> (,,) name nameKind <$> (g val >>= g')) ds-  f' (TypeClassDeclaration name args implies ds) = TypeClassDeclaration name args implies <$> mapM (f' <=< f) ds-  f' (TypeInstanceDeclaration name cs className args ds) = TypeInstanceDeclaration name cs className args <$> mapM (f' <=< f) ds-  f' (PositionedDeclaration pos d) = PositionedDeclaration pos <$> (f d >>= f')-  f' other = f other--  g' (UnaryMinus v) = UnaryMinus <$> (g v >>= g')-  g' (BinaryNoParens op v1 v2) = BinaryNoParens op <$> (g v1 >>= g') <*> (g v2 >>= g')-  g' (Parens v) = Parens <$> (g v >>= g')-  g' (ArrayLiteral vs) = ArrayLiteral <$> mapM (g' <=< g) vs-  g' (ObjectLiteral vs) = ObjectLiteral <$> mapM (sndM (g' <=< g)) vs-  g' (TypeClassDictionaryConstructorApp name v) = TypeClassDictionaryConstructorApp name <$> (g v >>= g')-  g' (Accessor prop v) = Accessor prop <$> (g v >>= g')-  g' (ObjectUpdate obj vs) = ObjectUpdate <$> (g obj >>= g') <*> mapM (sndM (g' <=< g)) vs-  g' (Abs name v) = Abs name <$> (g v >>= g')-  g' (App v1 v2) = App <$> (g v1 >>= g') <*> (g v2 >>= g')-  g' (IfThenElse v1 v2 v3) = IfThenElse <$> (g v1 >>= g') <*> (g v2 >>= g') <*> (g v3 >>= g')-  g' (Case vs alts) = Case <$> mapM (g' <=< g) vs <*> mapM handleCaseAlternative alts-  g' (TypedValue check v ty) = TypedValue check <$> (g v >>= g') <*> pure ty-  g' (Let ds v) = Let <$> mapM (f' <=< f) ds <*> (g v >>= g')-  g' (Do es) = Do <$> mapM handleDoNotationElement es-  g' (PositionedValue pos v) = PositionedValue pos <$> (g v >>= g')-  g' other = g other--  h' (ConstructorBinder ctor bs) = ConstructorBinder ctor <$> mapM (h' <=< h) bs-  h' (ObjectBinder bs) = ObjectBinder <$> mapM (sndM (h' <=< h)) bs-  h' (ArrayBinder bs) = ArrayBinder <$> mapM (h' <=< h) bs-  h' (ConsBinder b1 b2) = ConsBinder <$> (h b1 >>= h') <*> (h b2 >>= h')-  h' (NamedBinder name b) = NamedBinder name <$> (h b >>= h')-  h' (PositionedBinder pos b) = PositionedBinder pos <$> (h b >>= h')-  h' other = h other--  handleCaseAlternative (CaseAlternative bs grd val) = CaseAlternative <$> mapM (h' <=< h) bs-                                                                       <*> maybeM (g' <=< g) grd-                                                                       <*> (g' <=< g) val--  handleDoNotationElement (DoNotationValue v) = DoNotationValue <$> (g' <=< g) v-  handleDoNotationElement (DoNotationBind b v) = DoNotationBind <$> (h' <=< h) b <*> (g' <=< g) v-  handleDoNotationElement (DoNotationLet ds) = DoNotationLet <$> mapM (f' <=< f) ds-  handleDoNotationElement (PositionedDoNotationElement pos e) = PositionedDoNotationElement pos <$> handleDoNotationElement e--everywhereOnValuesM :: (Functor m, Applicative m, Monad m) =>-  (Declaration -> m Declaration) ->-  (Expr -> m Expr) ->-  (Binder -> m Binder) ->-  (Declaration -> m Declaration, Expr -> m Expr, Binder -> m Binder)-everywhereOnValuesM f g h = (f' <=< f, g' <=< g, h' <=< h)-  where-  f' (DataBindingGroupDeclaration ds) = (DataBindingGroupDeclaration <$> mapM f' ds) >>= f-  f' (ValueDeclaration name nameKind bs grd val) = (ValueDeclaration name nameKind <$> mapM h' bs <*> maybeM g' grd <*> g' val) >>= f-  f' (BindingGroupDeclaration ds) = (BindingGroupDeclaration <$> mapM (\(name, nameKind, val) -> (,,) name nameKind <$> g' val) ds) >>= f-  f' (TypeClassDeclaration name args implies ds) = (TypeClassDeclaration name args implies <$> mapM f' ds) >>= f-  f' (TypeInstanceDeclaration name cs className args ds) = (TypeInstanceDeclaration name cs className args <$> mapM f' ds) >>= f-  f' (PositionedDeclaration pos d) = (PositionedDeclaration pos <$> f' d) >>= f-  f' other = f other--  g' (UnaryMinus v) = (UnaryMinus <$> g' v) >>= g-  g' (BinaryNoParens op v1 v2) = (BinaryNoParens op <$> (g' v1) <*> (g' v2)) >>= g-  g' (Parens v) = (Parens <$> g' v) >>= g-  g' (ArrayLiteral vs) = (ArrayLiteral <$> mapM g' vs) >>= g-  g' (ObjectLiteral vs) = (ObjectLiteral <$> mapM (sndM g') vs) >>= g-  g' (TypeClassDictionaryConstructorApp name v) = (TypeClassDictionaryConstructorApp name <$> g' v) >>= g-  g' (Accessor prop v) = (Accessor prop <$> g' v) >>= g-  g' (ObjectUpdate obj vs) = (ObjectUpdate <$> g' obj <*> mapM (sndM g') vs) >>= g-  g' (Abs name v) = (Abs name <$> g' v) >>= g-  g' (App v1 v2) = (App <$> g' v1 <*> g' v2) >>= g-  g' (IfThenElse v1 v2 v3) = (IfThenElse <$> g' v1 <*> g' v2 <*> g' v3) >>= g-  g' (Case vs alts) = (Case <$> mapM g' vs <*> mapM handleCaseAlternative alts) >>= g-  g' (TypedValue check v ty) = (TypedValue check <$> g' v <*> pure ty) >>= g-  g' (Let ds v) = (Let <$> mapM f' ds <*> g' v) >>= g-  g' (Do es) = (Do <$> mapM handleDoNotationElement es) >>= g-  g' (PositionedValue pos v) = (PositionedValue pos <$> g' v) >>= g-  g' other = g other--  h' (ConstructorBinder ctor bs) = (ConstructorBinder ctor <$> mapM h' bs) >>= h-  h' (ObjectBinder bs) = (ObjectBinder <$> mapM (sndM h') bs) >>= h-  h' (ArrayBinder bs) = (ArrayBinder <$> mapM h' bs) >>= h-  h' (ConsBinder b1 b2) = (ConsBinder <$> h' b1 <*> h' b2) >>= h-  h' (NamedBinder name b) = (NamedBinder name <$> h' b) >>= h-  h' (PositionedBinder pos b) = (PositionedBinder pos <$> h' b) >>= h-  h' other = h other--  handleCaseAlternative (CaseAlternative bs grd val) = CaseAlternative <$> mapM h' bs-                                                                       <*> maybeM g' grd-                                                                       <*> g' val--  handleDoNotationElement (DoNotationValue v) = DoNotationValue <$> g' v-  handleDoNotationElement (DoNotationBind b v) = DoNotationBind <$> h' b <*> g' v-  handleDoNotationElement (DoNotationLet ds) = DoNotationLet <$> mapM f' ds-  handleDoNotationElement (PositionedDoNotationElement pos e) = PositionedDoNotationElement pos <$> handleDoNotationElement e--everythingOnValues :: (r -> r -> r) ->-                      (Declaration -> r) ->-                      (Expr -> r) ->-                      (Binder -> r) ->-                      (CaseAlternative -> r) ->-                      (DoNotationElement -> r) ->-                      (Declaration -> r, Expr -> r, Binder -> r, CaseAlternative -> r, DoNotationElement -> r)-everythingOnValues (<>) f g h i j = (f', g', h', i', j')-  where-  f' d@(DataBindingGroupDeclaration ds) = foldl (<>) (f d) (map f' ds)-  f' d@(ValueDeclaration _ _ bs Nothing val) = foldl (<>) (f d) (map h' bs) <> g' val-  f' d@(ValueDeclaration _ _ bs (Just grd) val) = foldl (<>) (f d) (map h' bs) <> g' grd <> g' val-  f' d@(BindingGroupDeclaration ds) = foldl (<>) (f d) (map (\(_, _, val) -> g' val) ds)-  f' d@(TypeClassDeclaration _ _ _ ds) = foldl (<>) (f d) (map f' ds)-  f' d@(TypeInstanceDeclaration _ _ _ _ ds) = foldl (<>) (f d) (map f' ds)-  f' d@(PositionedDeclaration _ d1) = f d <> f' d1-  f' d = f d--  g' v@(UnaryMinus v1) = g v <> g' v1-  g' v@(BinaryNoParens _ v1 v2) = g v <> g' v1 <> g' v2-  g' v@(Parens v1) = g v <> g' v1-  g' v@(ArrayLiteral vs) = foldl (<>) (g v) (map g' vs)-  g' v@(ObjectLiteral vs) = foldl (<>) (g v) (map (g' . snd) vs)-  g' v@(TypeClassDictionaryConstructorApp _ v1) = g v <> g' v1-  g' v@(Accessor _ v1) = g v <> g' v1-  g' v@(ObjectUpdate obj vs) = foldl (<>) (g v <> g' obj) (map (g' . snd) vs)-  g' v@(Abs _ v1) = g v <> g' v1-  g' v@(App v1 v2) = g v <> g' v1 <> g' v2-  g' v@(IfThenElse v1 v2 v3) = g v <> g' v1 <> g' v2 <> g' v3-  g' v@(Case vs alts) = foldl (<>) (foldl (<>) (g v) (map g' vs)) (map i' alts)-  g' v@(TypedValue _ v1 _) = g v <> g' v1-  g' v@(Let ds v1) = (foldl (<>) (g v) (map f' ds)) <> g' v1-  g' v@(Do es) = foldl (<>) (g v) (map j' es)-  g' v@(PositionedValue _ v1) = g v <> g' v1-  g' v = g v--  h' b@(ConstructorBinder _ bs) = foldl (<>) (h b) (map h' bs)-  h' b@(ObjectBinder bs) = foldl (<>) (h b) (map (h' . snd) bs)-  h' b@(ArrayBinder bs) = foldl (<>) (h b) (map h' bs)-  h' b@(ConsBinder b1 b2) = h b <> h' b1 <> h' b2-  h' b@(NamedBinder _ b1) = h b <> h' b1-  h' b@(PositionedBinder _ b1) = h b <> h' b1-  h' b = h b--  i' ca = case caseAlternativeGuard ca of-    Nothing -> foldl (<>) (i ca) (map h' (caseAlternativeBinders ca)) <> g' (caseAlternativeResult ca)-    Just grd -> foldl (<>) (i ca) (map h' (caseAlternativeBinders ca)) <> g' grd <> g' (caseAlternativeResult ca)--  j' e@(DoNotationValue v) = j e <> g' v-  j' e@(DoNotationBind b v) = j e <> h' b <> g' v-  j' e@(DoNotationLet ds) = foldl (<>) (j e) (map f' ds)-  j' e@(PositionedDoNotationElement _ e1) = j e <> j' e1--everythingWithContextOnValues ::-  s ->-  r ->-  (r -> r -> r) ->-  (s -> Declaration       -> (s, r)) ->-  (s -> Expr             -> (s, r)) ->-  (s -> Binder            -> (s, r)) ->-  (s -> CaseAlternative   -> (s, r)) ->-  (s -> DoNotationElement -> (s, r)) ->-  ( Declaration       -> r-  , Expr             -> r-  , Binder            -> r-  , CaseAlternative   -> r-  , DoNotationElement -> r)-everythingWithContextOnValues s0 r0 (<>) f g h i j = (f'' s0, g'' s0, h'' s0, i'' s0, j'' s0)-  where-  f'' s d = let (s', r) = f s d in r <> f' s' d--  f' s (DataBindingGroupDeclaration ds) = foldl (<>) r0 (map (f'' s) ds)-  f' s (ValueDeclaration _ _ bs Nothing val) = foldl (<>) r0 (map (h'' s) bs) <> (g'' s) val-  f' s (ValueDeclaration _ _ bs (Just grd) val) = foldl (<>) r0 (map (h'' s) bs) <> (g'' s) grd <> (g'' s) val-  f' s (BindingGroupDeclaration ds) = foldl (<>) r0 (map (\(_, _, val) -> (g'' s) val) ds)-  f' s (TypeClassDeclaration _ _ _ ds) = foldl (<>) r0 (map (f'' s) ds)-  f' s (TypeInstanceDeclaration _ _ _ _ ds) = foldl (<>) r0 (map (f'' s) ds)-  f' s (PositionedDeclaration _ d1) = (f'' s) d1-  f' _ _ = r0--  g'' s v = let (s', r) = g s v in r <> g' s' v--  g' s (UnaryMinus v1) = (g'' s) v1-  g' s (BinaryNoParens _ v1 v2) = (g'' s) v1 <> (g'' s) v2-  g' s (Parens v1) = (g'' s) v1-  g' s (ArrayLiteral vs) = foldl (<>) r0 (map (g'' s) vs)-  g' s (ObjectLiteral vs) = foldl (<>) r0 (map (g'' s . snd) vs)-  g' s (TypeClassDictionaryConstructorApp _ v1) = (g'' s) v1-  g' s (Accessor _ v1) = (g'' s) v1-  g' s (ObjectUpdate obj vs) = foldl (<>) ((g'' s) obj) (map (g'' s . snd) vs)-  g' s (Abs _ v1) = (g'' s) v1-  g' s (App v1 v2) = (g'' s) v1 <> (g'' s) v2-  g' s (IfThenElse v1 v2 v3) = (g'' s) v1 <> (g'' s) v2 <> (g'' s) v3-  g' s (Case vs alts) = foldl (<>) (foldl (<>) r0 (map (g'' s) vs)) (map (i'' s) alts)-  g' s (TypedValue _ v1 _) = (g'' s) v1-  g' s (Let ds v1) = (foldl (<>) r0 (map (f'' s) ds)) <> (g'' s) v1-  g' s (Do es) = foldl (<>) r0 (map (j'' s) es)-  g' s (PositionedValue _ v1) = (g'' s) v1-  g' _ _ = r0--  h'' s b = let (s', r) = h s b in r <> h' s' b--  h' s (ConstructorBinder _ bs) = foldl (<>) r0 (map (h'' s) bs)-  h' s (ObjectBinder bs) = foldl (<>) r0 (map (h'' s . snd) bs)-  h' s (ArrayBinder bs) = foldl (<>) r0 (map (h'' s) bs)-  h' s (ConsBinder b1 b2) = (h'' s) b1 <> (h'' s) b2-  h' s (NamedBinder _ b1) = (h'' s) b1-  h' s (PositionedBinder _ b1) = (h'' s) b1-  h' _ _ = r0--  i'' s ca = let (s', r) = i s ca in r <> i' s' ca--  i' s (CaseAlternative bs Nothing val) = foldl (<>) r0 (map (h'' s) bs) <> (g'' s) val-  i' s (CaseAlternative bs (Just grd) val) = foldl (<>) r0 (map (h'' s) bs) <> (g'' s) grd <> (g'' s) val--  j'' s e = let (s', r) = j s e in r <> j' s' e--  j' s (DoNotationValue v) = (g'' s) v-  j' s (DoNotationBind b v) =  (h'' s) b <> (g'' s) v-  j' s (DoNotationLet ds) = foldl (<>) r0 (map (f'' s) ds)-  j' s (PositionedDoNotationElement _ e1) = (j'' s) e1--everywhereWithContextOnValuesM :: (Functor m, Applicative m, Monad m) =>-  s ->-  (s -> Declaration       -> m (s, Declaration)) ->-  (s -> Expr             -> m (s, Expr)) ->-  (s -> Binder            -> m (s, Binder)) ->-  (s -> CaseAlternative   -> m (s, CaseAlternative)) ->-  (s -> DoNotationElement -> m (s, DoNotationElement)) ->-  ( Declaration       -> m Declaration-  , Expr             -> m Expr-  , Binder            -> m Binder-  , CaseAlternative   -> m CaseAlternative-  , DoNotationElement -> m DoNotationElement)-everywhereWithContextOnValuesM s0 f g h i j = (f'' s0, g'' s0, h'' s0, i'' s0, j'' s0)-  where-  f'' s = uncurry f' <=< f s--  f' s (DataBindingGroupDeclaration ds) = DataBindingGroupDeclaration <$> mapM (f'' s) ds-  f' s (ValueDeclaration name nameKind bs grd val) = ValueDeclaration name nameKind <$> mapM (h'' s) bs <*> maybeM (g'' s) grd <*> g'' s val-  f' s (BindingGroupDeclaration ds) = BindingGroupDeclaration <$> mapM (thirdM (g'' s)) ds-  f' s (TypeClassDeclaration name args implies ds) = TypeClassDeclaration name args implies <$> mapM (f'' s) ds-  f' s (TypeInstanceDeclaration name cs className args ds) = TypeInstanceDeclaration name cs className args <$> mapM (f'' s) ds-  f' s (PositionedDeclaration pos d1) = PositionedDeclaration pos <$> f'' s d1-  f' _ other = return other--  g'' s = uncurry g' <=< g s--  g' s (UnaryMinus v) = UnaryMinus <$> g'' s v-  g' s (BinaryNoParens op v1 v2) = BinaryNoParens op <$> g'' s v1 <*> g'' s v2-  g' s (Parens v) = Parens <$> g'' s v-  g' s (ArrayLiteral vs) = ArrayLiteral <$> mapM (g'' s) vs-  g' s (ObjectLiteral vs) = ObjectLiteral <$> mapM (sndM (g'' s)) vs-  g' s (TypeClassDictionaryConstructorApp name v) = TypeClassDictionaryConstructorApp name <$> (g'' s) v-  g' s (Accessor prop v) = Accessor prop <$> g'' s v-  g' s (ObjectUpdate obj vs) = ObjectUpdate <$> g'' s obj <*> mapM (sndM (g'' s)) vs-  g' s (Abs name v) = Abs name <$> g'' s v-  g' s (App v1 v2) = App <$> g'' s v1 <*> g'' s v2-  g' s (IfThenElse v1 v2 v3) = IfThenElse <$> g'' s v1 <*> g'' s v2 <*> g'' s v3-  g' s (Case vs alts) = Case <$> mapM (g'' s) vs <*> mapM (i'' s) alts-  g' s (TypedValue check v ty) = TypedValue check <$> g'' s v <*> pure ty-  g' s (Let ds v) = Let <$> mapM (f'' s) ds <*> g'' s v-  g' s (Do es) = Do <$> mapM (j'' s) es-  g' s (PositionedValue pos v) = PositionedValue pos <$> g'' s v-  g' _ other = return other--  h'' s = uncurry h' <=< h s--  h' s (ConstructorBinder ctor bs) = ConstructorBinder ctor <$> mapM (h'' s) bs-  h' s (ObjectBinder bs) = ObjectBinder <$> mapM (sndM (h'' s)) bs-  h' s (ArrayBinder bs) = ArrayBinder <$> mapM (h'' s) bs-  h' s (ConsBinder b1 b2) = ConsBinder <$> h'' s b1 <*> h'' s b2-  h' s (NamedBinder name b) = NamedBinder name <$> h'' s b-  h' s (PositionedBinder pos b) = PositionedBinder pos <$> h'' s b-  h' _ other = return other--  i'' s = uncurry i' <=< i s--  i' s (CaseAlternative bs grd val) = CaseAlternative <$> mapM (h'' s) bs <*> maybeM (g'' s) grd <*> g'' s val--  j'' s = uncurry j' <=< j s--  j' s (DoNotationValue v) = DoNotationValue <$> g'' s v-  j' s (DoNotationBind b v) = DoNotationBind <$> h'' s b <*> g'' s v-  j' s (DoNotationLet ds) = DoNotationLet <$> mapM (f'' s) ds-  j' s (PositionedDoNotationElement pos e1) = PositionedDoNotationElement pos <$> j'' s e1--accumTypes :: (Monoid r) => (Type -> r) -> (Declaration -> r, Expr -> r, Binder -> r, CaseAlternative -> r, DoNotationElement -> r)-accumTypes f = everythingOnValues mappend forDecls forValues (const mempty) (const mempty) (const mempty)-  where-  forDecls (DataDeclaration _ _ _ dctors) = mconcat (concatMap (map f . snd) dctors)-  forDecls (ExternDeclaration _ _ _ ty) = f ty-  forDecls (ExternInstanceDeclaration _ cs _ tys) = mconcat (concatMap (map f . snd) cs) `mappend` mconcat (map f tys)-  forDecls (TypeClassDeclaration _ _ implies _) = mconcat (concatMap (map f . snd) implies)-  forDecls (TypeInstanceDeclaration _ cs _ tys _) = mconcat (concatMap (map f . snd) cs) `mappend` mconcat (map f tys)-  forDecls (TypeSynonymDeclaration _ _ ty) = f ty-  forDecls (TypeDeclaration _ ty) = f ty-  forDecls _ = mempty--  forValues (TypeClassDictionary _ (_, cs) _) = mconcat (map f cs)-  forValues (SuperClassDictionary _ tys) = mconcat (map f tys)-  forValues (TypedValue _ _ ty) = f ty-  forValues _ = mempty--
src/Language/PureScript/Errors.hs view
@@ -23,7 +23,7 @@ import Control.Monad.Error import Control.Applicative ((<$>)) -import Language.PureScript.Declarations+import Language.PureScript.AST import Language.PureScript.Pretty import Language.PureScript.Types 
src/Language/PureScript/ModuleDependencies.hs view
@@ -21,7 +21,7 @@ import Data.List (nub) import Data.Maybe (mapMaybe) -import Language.PureScript.Declarations+import Language.PureScript.AST import Language.PureScript.Names import Language.PureScript.Types 
src/Language/PureScript/Parser/Common.hs view
@@ -134,6 +134,12 @@ identifier = PT.identifier tokenParser  -- |+-- Parse an identifier in a more permissive position+--+identifierName :: P.Parsec String u String+identifierName = lexeme $ (:) <$> identStart <*> many identLetter++-- | -- Parse a reserved word -- reserved :: String -> P.Parsec String u ()
src/Language/PureScript/Parser/Declarations.hs view
@@ -35,7 +35,7 @@ import Language.PureScript.Kinds import Language.PureScript.Parser.State import Language.PureScript.Parser.Common-import Language.PureScript.Declarations+import Language.PureScript.AST import Language.PureScript.Parser.Types import Language.PureScript.Parser.Kinds import Language.PureScript.CodeGen.JS.AST@@ -54,7 +54,7 @@   toSourcePos p = SourcePos (P.sourceName p) (P.sourceLine p) (P.sourceColumn p)  kindedIdent :: P.Parsec String ParseState (String, Maybe Kind)-kindedIdent = (, Nothing) <$> identifier +kindedIdent = (, Nothing) <$> identifier           <|> parens ((,) <$> identifier <*> (Just <$> (indented *> lexeme (P.string "::") *> indented *> parseKind)))  parseDataDeclaration :: P.Parsec String ParseState Declaration@@ -64,7 +64,7 @@   tyArgs <- many (indented *> kindedIdent)   ctors <- P.option [] $ do     _ <- lexeme $ indented *> P.char '='-    sepBy1 ((,) <$> properName <*> P.many (indented *> parseTypeAtom)) pipe+    sepBy1 ((,) <$> properName <*> P.many (indented *> noWildcards parseTypeAtom)) pipe   return $ DataDeclaration dtype name tyArgs ctors  parseTypeDeclaration :: P.Parsec String ParseState Declaration@@ -76,20 +76,28 @@ parseTypeSynonymDeclaration =   TypeSynonymDeclaration <$> (P.try (reserved "type") *> indented *> properName)                          <*> many (indented *> kindedIdent)-                         <*> (lexeme (indented *> P.char '=') *> parsePolyType)+                         <*> (lexeme (indented *> P.char '=') *> noWildcards parsePolyType)  parseValueDeclaration :: P.Parsec String ParseState Declaration parseValueDeclaration = do   name <- parseIdent   binders <- P.many parseBinderNoParens-  guard <- P.optionMaybe parseGuard-  value <- lexeme (indented *> P.char '=') *> parseValue-  whereClause <- P.optionMaybe $ do-    C.indented-    reserved "where"-    C.indented-    C.mark $ P.many1 (C.same *> parseLocalDeclaration)-  return $ ValueDeclaration name Value binders guard (maybe value (`Let` value) whereClause)+  value <- Left <$> (C.indented *>+                       C.mark (P.many1 ((,) <$> (C.same *> parseGuard)+                                            <*> (lexeme (indented *> P.char '=') *> parseValueWithWhereClause)+                                       )))+       <|> Right <$> (lexeme (indented *> P.char '=') *> parseValueWithWhereClause)+  return $ ValueDeclaration name Value binders value+  where+  parseValueWithWhereClause :: P.Parsec String ParseState Expr+  parseValueWithWhereClause = do+    value <- parseValue+    whereClause <- P.optionMaybe $ do+      C.indented+      reserved "where"+      C.indented+      C.mark $ P.many1 (C.same *> parseLocalDeclaration)+    return $ maybe value (`Let` value) whereClause  parseExternDeclaration :: P.Parsec String ParseState Declaration parseExternDeclaration = P.try (reserved "foreign") *> indented *> reserved "import" *> indented *>@@ -98,16 +106,16 @@    <|> (do reserved "instance"            name <- parseIdent <* lexeme (indented *> P.string "::")            deps <- P.option [] $ do-             deps <- parens (commaSep1 ((,) <$> parseQualified properName <*> P.many parseTypeAtom))+             deps <- parens (commaSep1 ((,) <$> parseQualified properName <*> P.many (noWildcards parseTypeAtom)))              indented              reservedOp "=>"              return deps            className <- indented *> parseQualified properName-           tys <- P.many (indented *> parseTypeAtom)+           tys <- P.many (indented *> noWildcards parseTypeAtom)            return $ ExternInstanceDeclaration name deps className tys)    <|> (do ident <- parseIdent            js <- P.optionMaybe (JSRaw <$> stringLiteral)-           ty <- lexeme (indented *> P.string "::") *> parsePolyType+           ty <- lexeme (indented *> P.string "::") *> noWildcards parsePolyType            return $ ExternDeclaration (if isJust js then InlineJavascript else ForeignImport) ident js ty))  parseAssociativity :: P.Parsec String ParseState Associativity@@ -168,7 +176,7 @@   reserved "class"   implies <- P.option [] $ do     indented-    implies <- parens (commaSep1 ((,) <$> parseQualified properName <*> P.many parseTypeAtom))+    implies <- parens (commaSep1 ((,) <$> parseQualified properName <*> P.many (noWildcards parseTypeAtom)))     reservedOp "<="     return implies   className <- indented *> properName@@ -183,12 +191,12 @@   reserved "instance"   name <- parseIdent <* lexeme (indented *> P.string "::")   deps <- P.optionMaybe $ do-    deps <- parens (commaSep1 ((,) <$> parseQualified properName <*> P.many parseTypeAtom))+    deps <- parens (commaSep1 ((,) <$> parseQualified properName <*> P.many (noWildcards parseTypeAtom)))     indented     reservedOp "=>"     return deps   className <- indented *> parseQualified properName-  ty <- P.many (indented *> parseTypeAtom)+  ty <- P.many (indented *> (noWildcards parseTypeAtom))   members <- P.option [] . P.try $ do     indented *> reserved "where"     mark (P.many (same *> positioned parseValueDeclaration))@@ -233,10 +241,10 @@   return $ Module name decls exports  -- |--- Parse a collection of modules +-- Parse a collection of modules -- parseModulesFromFiles :: (k -> String) -> [(k, String)] -> Either P.ParseError [(k, Module)]-parseModulesFromFiles toFilePath input = +parseModulesFromFiles toFilePath input =   fmap collect . forM input $ \(filename, content) -> do     ms <- runIndentParser (toFilePath filename) parseModules content     return (filename, ms)@@ -269,7 +277,7 @@ parseObjectLiteral = ObjectLiteral <$> C.braces (C.commaSep parseIdentifierAndValue)  parseIdentifierAndValue :: P.Parsec String ParseState (String, Expr)-parseIdentifierAndValue = (,) <$> (C.indented *> (C.identifier <|> C.stringLiteral) <* C.indented <* C.colon)+parseIdentifierAndValue = (,) <$> (C.indented *> (C.identifierName <|> C.stringLiteral) <* C.indented <* C.colon)                               <*> (C.indented *> parseValue)  parseAbs :: P.Parsec String ParseState Expr@@ -295,8 +303,11 @@  parseCaseAlternative :: P.Parsec String ParseState CaseAlternative parseCaseAlternative = CaseAlternative <$> (return <$> parseBinder)-                                       <*> P.optionMaybe parseGuard-                                       <*> (C.indented *> C.reservedOp "->" *> parseValue)+                                       <*> (Left <$> (C.indented *>+                                                        C.mark (P.many1 ((,) <$> (C.same *> parseGuard)+                                                                             <*> (lexeme (indented *> C.reservedOp "->") *> parseValue)+                                                                        )))+                                            <|> Right <$> (lexeme (indented *> C.reservedOp "->") *> parseValue))                                        P.<?> "case alternative"  parseIfThenElse :: P.Parsec String ParseState Expr@@ -332,14 +343,14 @@  parsePropertyUpdate :: P.Parsec String ParseState (String, Expr) parsePropertyUpdate = do-  name <- C.lexeme (C.identifier <|> C.stringLiteral)+  name <- C.lexeme (C.identifierName <|> C.stringLiteral)   _ <- C.lexeme $ C.indented *> P.char '='   value <- C.indented *> parseValue   return (name, value)  parseAccessor :: Expr -> P.Parsec String ParseState Expr parseAccessor (Constructor _) = P.unexpected "constructor"-parseAccessor obj = P.try $ Accessor <$> (C.indented *> C.dot *> P.notFollowedBy C.opLetter *> C.indented *> (C.identifier <|> C.stringLiteral)) <*> pure obj+parseAccessor obj = P.try $ Accessor <$> (C.indented *> C.dot *> P.notFollowedBy C.opLetter *> C.indented *> (C.identifierName <|> C.stringLiteral)) <*> pure obj  parseDo :: P.Parsec String ParseState Expr parseDo = do@@ -419,7 +430,7 @@  parseIdentifierAndBinder :: P.Parsec String ParseState (String, Binder) parseIdentifierAndBinder = do-  name <- C.lexeme (C.identifier <|> C.stringLiteral)+  name <- C.lexeme (C.identifierName <|> C.stringLiteral)   _ <- C.lexeme $ C.indented *> P.char '='   binder <- C.indented *> parseBinder   return (name, binder)@@ -464,6 +475,6 @@ -- Parse a guard -- parseGuard :: P.Parsec String ParseState Guard-parseGuard = C.indented *> C.pipe *> C.indented *> parseValue+parseGuard = C.pipe *> C.indented *> parseValue  
src/Language/PureScript/Parser/Types.hs view
@@ -16,6 +16,7 @@ module Language.PureScript.Parser.Types (     parseType,     parsePolyType,+    noWildcards,     parseTypeAtom ) where @@ -43,6 +44,9 @@ parseObject :: P.Parsec String ParseState Type parseObject = braces $ TypeApp tyObject <$> parseRow +parseTypeWildcard :: P.Parsec String ParseState Type+parseTypeWildcard = lexeme (P.char '_') >> return TypeWildcard+ parseTypeVariable :: P.Parsec String ParseState Type parseTypeVariable = do   ident <- identifier@@ -65,6 +69,7 @@             , parseArrayOf             , parseFunction             , parseObject+            , parseTypeWildcard             , parseTypeVariable             , parseTypeConstructor             , parseForAll@@ -108,8 +113,17 @@ parsePolyType :: P.Parsec String ParseState Type parsePolyType = parseAnyType +-- |+-- Parse an atomic type with no wildcards+--+noWildcards :: P.Parsec String ParseState Type -> P.Parsec String ParseState Type+noWildcards p = do+  ty <- p+  when (containsWildcards ty) $ P.unexpected "type wildcard"+  return ty+ parseNameAndType :: P.Parsec String ParseState t -> P.Parsec String ParseState (String, t)-parseNameAndType p = (,) <$> (indented *> (identifier <|> stringLiteral) <* indented <* lexeme (P.string "::")) <*> p+parseNameAndType p = (,) <$> (indented *> (identifierName <|> stringLiteral) <* indented <* lexeme (P.string "::")) <*> p  parseRowEnding :: P.Parsec String ParseState Type parseRowEnding = P.option REmpty (TypeVar <$> (lexeme (indented *> P.char '|') *> indented *> identifier))
src/Language/PureScript/Pretty/Types.hs view
@@ -34,6 +34,7 @@ typeLiterals :: Pattern () Type String typeLiterals = mkPattern match   where+  match TypeWildcard = Just "_"         match (TypeVar var) = Just var   match (PrettyPrintObject row) = Just $ "{ " ++ prettyPrintRow row ++ " }"   match (PrettyPrintArray ty) = Just $ "[" ++ prettyPrintType ty ++ "]"
src/Language/PureScript/Pretty/Values.hs view
@@ -26,7 +26,7 @@ import Control.Monad.State import Control.Applicative -import Language.PureScript.Declarations+import Language.PureScript.AST import Language.PureScript.Pretty.Common import Language.PureScript.Pretty.Types (prettyPrintType) @@ -86,7 +86,7 @@  prettyPrintDeclaration :: Declaration -> StateT PrinterState Maybe String prettyPrintDeclaration (TypeDeclaration ident ty) = return $ show ident ++ " :: " ++ prettyPrintType ty-prettyPrintDeclaration (ValueDeclaration ident _ [] Nothing val) = fmap concat $ sequence+prettyPrintDeclaration (ValueDeclaration ident _ [] (Right val)) = fmap concat $ sequence   [ return $ show ident ++ " = "   , prettyPrintValue' val   ]@@ -94,13 +94,23 @@ prettyPrintDeclaration _ = error "Invalid argument to prettyPrintDeclaration"  prettyPrintCaseAlternative :: CaseAlternative -> StateT PrinterState Maybe String-prettyPrintCaseAlternative (CaseAlternative binders grd val) =+prettyPrintCaseAlternative (CaseAlternative binders result) =   fmap concat $ sequence     [ intercalate ", " <$> forM binders prettyPrintBinder'-    , maybe (return "") (fmap ("| " ++) . prettyPrintValue') grd-    , return " -> "-    , prettyPrintValue' val+    , prettyPrintResult result     ]+  where+  prettyPrintResult (Left gs) = concat <$> mapM prettyPrintGuardedValue gs+  prettyPrintResult (Right v) = (" -> " ++) <$> prettyPrintValue' v++  prettyPrintGuardedValue (grd, val) =+    fmap concat $ sequence+      [ return "| "+      , prettyPrintValue' grd+      , return " -> "+      , prettyPrintValue' val+      , return "\n"+      ]  prettyPrintDoNotationElement :: DoNotationElement -> StateT PrinterState Maybe String prettyPrintDoNotationElement (DoNotationValue val) =
src/Language/PureScript/Renamer.hs view
@@ -23,7 +23,7 @@ import qualified Data.Map as M import qualified Data.Set as S -import Language.PureScript.Declarations+import Language.PureScript.AST import Language.PureScript.Environment import Language.PureScript.Names import Language.PureScript.Traversals@@ -103,7 +103,7 @@ findDeclIdents :: [Declaration] -> [Ident] findDeclIdents = concatMap go   where-  go (ValueDeclaration ident _ _ _ _) = [ident]+  go (ValueDeclaration ident _ _ _) = [ident]   go (BindingGroupDeclaration ds) = map (\(name, _, _) -> name) ds   go (ExternDeclaration _ ident _ _) = [ident]   go (TypeClassDeclaration _ _ _ ds) = findDeclIdents ds@@ -129,9 +129,9 @@ -- another in the current scope. -- renameInDecl :: Bool -> Declaration -> Rename Declaration-renameInDecl isTopLevel (ValueDeclaration name nameKind [] Nothing val) = do+renameInDecl isTopLevel (ValueDeclaration name nameKind [] (Right val)) = do   name' <- if isTopLevel then return name else updateScope name-  ValueDeclaration name' nameKind [] Nothing <$> renameInValue val+  ValueDeclaration name' nameKind [] . Right <$> renameInValue val renameInDecl isTopLevel (BindingGroupDeclaration ds) = do   ds' <- mapM updateNames ds   BindingGroupDeclaration <$> mapM updateValues ds'@@ -187,8 +187,9 @@ -- Renames within case alternatives. -- renameInCaseAlternative :: CaseAlternative -> Rename CaseAlternative-renameInCaseAlternative (CaseAlternative bs g v) =-  CaseAlternative <$> mapM renameInBinder bs <*> maybeM renameInValue g <*> renameInValue v+renameInCaseAlternative (CaseAlternative bs v) =+  CaseAlternative <$> mapM renameInBinder bs+                  <*> eitherM (mapM (pairM renameInValue renameInValue)) renameInValue v  -- | -- Renames within binders.
src/Language/PureScript/Sugar.hs view
@@ -19,7 +19,7 @@ import Control.Category ((>>>)) import Control.Monad.Trans.Class -import Language.PureScript.Declarations+import Language.PureScript.AST import Language.PureScript.Errors import Language.PureScript.Supply 
src/Language/PureScript/Sugar/BindingGroups.hs view
@@ -29,7 +29,7 @@  import qualified Data.Set as S -import Language.PureScript.Declarations+import Language.PureScript.AST import Language.PureScript.Names import Language.PureScript.Types import Language.PureScript.Environment@@ -84,7 +84,7 @@ collapseBindingGroups = let (f, _, _) = everywhereOnValues id collapseBindingGroupsForValue id in map f . concatMap go   where   go (DataBindingGroupDeclaration ds) = ds-  go (BindingGroupDeclaration ds) = map (\(ident, nameKind, val) -> ValueDeclaration ident nameKind [] Nothing val) ds+  go (BindingGroupDeclaration ds) = map (\(ident, nameKind, val) -> ValueDeclaration ident nameKind [] (Right val)) ds   go (PositionedDeclaration pos d) = map (PositionedDeclaration pos) $ go d   go other = [other] @@ -98,13 +98,13 @@   in nub . f   where   def s _ = (s, [])-  +   usedNamesE :: S.Set Ident -> Expr -> (S.Set Ident, [Ident])   usedNamesE scope (Var (Qualified Nothing name)) | name `S.notMember` scope = (scope, [name])   usedNamesE scope (Var (Qualified (Just moduleName') name)) | moduleName == moduleName' && name `S.notMember` scope = (scope, [name])   usedNamesE scope (Abs (Left name) _) = (name `S.insert` scope, [])   usedNamesE scope _ = (scope, [])-  +   usedNamesB :: S.Set Ident -> Binder -> (S.Set Ident, [Ident])   usedNamesB scope binder = (scope `S.union` S.fromList (binderNames binder), []) @@ -114,7 +114,7 @@   in nub . f   where   def s _ = (s, [])-  +   usedNamesE :: Bool -> Expr -> (Bool, [Ident])   usedNamesE True (Var (Qualified Nothing name)) = (True, [name])   usedNamesE True (Var (Qualified (Just moduleName') name)) | moduleName == moduleName' = (True, [name])@@ -135,7 +135,7 @@   usedNames _ = []  getIdent :: Declaration -> Ident-getIdent (ValueDeclaration ident _ _ _ _) = ident+getIdent (ValueDeclaration ident _ _ _) = ident getIdent (PositionedDeclaration _ d) = getIdent d getIdent _ = error "Expected ValueDeclaration" @@ -147,8 +147,8 @@  -- | -- Convert a group of mutually-recursive dependencies into a BindingGroupDeclaration (or simple ValueDeclaration).---  --+-- toBindingGroup :: ModuleName -> SCC Declaration -> Either ErrorStack Declaration toBindingGroup _ (AcyclicSCC d) = return d toBindingGroup _ (CyclicSCC [d]) = return d@@ -176,7 +176,7 @@    cycleError :: Declaration -> [Declaration] -> Either ErrorStack a   cycleError (PositionedDeclaration p d) ds = rethrowWithPosition p $ cycleError d ds-  cycleError (ValueDeclaration n _ _ _ e) [] = Left $+  cycleError (ValueDeclaration n _ _ (Right e)) [] = Left $     mkErrorStack ("Cycle in definition of " ++ show n) (Just (ExprError e))   cycleError d ds@(_:_) = rethrow (<> mkErrorStack ("The following are not yet defined here: " ++ unwords (map (show . getIdent) ds)) Nothing) $ cycleError d []   cycleError _ _ = error "Expected ValueDeclaration"@@ -197,7 +197,7 @@ isTypeSynonym _ = Nothing  fromValueDecl :: Declaration -> (Ident, NameKind, Expr)-fromValueDecl (ValueDeclaration ident nameKind [] Nothing val) = (ident, nameKind, val)+fromValueDecl (ValueDeclaration ident nameKind [] (Right val)) = (ident, nameKind, val) fromValueDecl ValueDeclaration{} = error "Binders should have been desugared" fromValueDecl (PositionedDeclaration _ d) = fromValueDecl d fromValueDecl _ = error "Expected ValueDeclaration"
src/Language/PureScript/Sugar/CaseDeclarations.hs view
@@ -19,7 +19,7 @@     desugarCasesModule ) where -import Data.Maybe (isJust)+import Data.Either (isLeft) import Data.Monoid ((<>)) import Data.List (nub, groupBy) @@ -28,10 +28,11 @@ import Control.Monad.Error.Class  import Language.PureScript.Names-import Language.PureScript.Declarations+import Language.PureScript.AST import Language.PureScript.Environment import Language.PureScript.Errors import Language.PureScript.Supply+import Language.PureScript.Traversals import Language.PureScript.TypeChecker.Monad (guardWith)  -- |@@ -50,7 +51,7 @@   replace :: Expr -> SupplyT (Either ErrorStack) Expr   replace (Abs (Right binder) val) = do     ident <- Ident <$> freshName-    return $ Abs (Left ident) $ Case [Var (Qualified Nothing ident)] [CaseAlternative [binder] Nothing val]+    return $ Abs (Left ident) $ Case [Var (Qualified Nothing ident)] [CaseAlternative [binder] (Right val)]   replace other = return other  -- |@@ -62,9 +63,11 @@     desugarRest :: [Declaration] -> SupplyT (Either ErrorStack) [Declaration]     desugarRest (TypeInstanceDeclaration name constraints className tys ds : rest) =       (:) <$> (TypeInstanceDeclaration name constraints className tys <$> desugarCases ds) <*> desugarRest rest-    desugarRest (ValueDeclaration name nameKind bs g val : rest) =+    desugarRest (ValueDeclaration name nameKind bs result : rest) =       let (_, f, _) = everywhereOnValuesTopDownM return go return-      in (:) <$> (ValueDeclaration name nameKind bs g <$> f val) <*> desugarRest rest+          f' (Left gs) = Left <$> mapM (pairM return f) gs+          f' (Right v) = Right <$> f v+      in (:) <$> (ValueDeclaration name nameKind bs <$> f' result) <*> desugarRest rest       where       go (Let ds val') = Let <$> desugarCases ds <*> pure val'       go other = return other@@ -75,22 +78,22 @@     desugarRest [] = pure []  inSameGroup :: Declaration -> Declaration -> Bool-inSameGroup (ValueDeclaration ident1 _ _ _ _) (ValueDeclaration ident2 _ _ _ _) = ident1 == ident2+inSameGroup (ValueDeclaration ident1 _ _ _) (ValueDeclaration ident2 _ _ _) = ident1 == ident2 inSameGroup (PositionedDeclaration _ d1) d2 = inSameGroup d1 d2 inSameGroup d1 (PositionedDeclaration _ d2) = inSameGroup d1 d2 inSameGroup _ _ = False  toDecls :: [Declaration] -> SupplyT (Either ErrorStack) [Declaration]-toDecls [ValueDeclaration ident nameKind bs Nothing val] | all isVarBinder bs = do+toDecls [ValueDeclaration ident nameKind bs (Right val)] | all isVarBinder bs = do   let args = map (\(VarBinder arg) -> arg) bs       body = foldr (Abs . Left) val args   guardWith (strMsg "Overlapping function argument names") $ length (nub args) == length args-  return [ValueDeclaration ident nameKind [] Nothing body]-toDecls ds@(ValueDeclaration ident _ bs g _ : _) = do+  return [ValueDeclaration ident nameKind [] (Right body)]+toDecls ds@(ValueDeclaration ident _ bs result : _) = do   let tuples = map toTuple ds   unless (all ((== length bs) . length . fst) tuples) $       throwError $ mkErrorStack ("Argument list lengths differ in declaration " ++ show ident) Nothing-  unless (not (null bs) || isJust g) $+  unless (not (null bs) || isLeft result) $       throwError $ mkErrorStack ("Duplicate value declaration '" ++ show ident ++ "'") Nothing   caseDecl <- makeCaseDeclaration ident tuples   return [caseDecl]@@ -103,18 +106,18 @@ isVarBinder (VarBinder _) = True isVarBinder _ = False -toTuple :: Declaration -> ([Binder], (Maybe Guard, Expr))-toTuple (ValueDeclaration _ _ bs g val) = (bs, (g, val))+toTuple :: Declaration -> ([Binder], Either [(Guard, Expr)] Expr)+toTuple (ValueDeclaration _ _ bs result) = (bs, result) toTuple (PositionedDeclaration _ d) = toTuple d toTuple _ = error "Not a value declaration" -makeCaseDeclaration :: Ident -> [([Binder], (Maybe Guard, Expr))] -> SupplyT (Either ErrorStack) Declaration+makeCaseDeclaration :: Ident -> [([Binder], Either [(Guard, Expr)] Expr)] -> SupplyT (Either ErrorStack) Declaration makeCaseDeclaration ident alternatives = do   let argPattern = length . fst . head $ alternatives   args <- map Ident <$> replicateM argPattern freshName   let     vars = map (Var . Qualified Nothing) args-    binders = [ CaseAlternative bs g val | (bs, (g, val)) <- alternatives ]+    binders = [ CaseAlternative bs result | (bs, result) <- alternatives ]     value = foldr (Abs . Left) (Case vars binders) args-  return $ ValueDeclaration ident Value [] Nothing value+  return $ ValueDeclaration ident Value [] (Right value) 
src/Language/PureScript/Sugar/DoNotation.hs view
@@ -19,7 +19,7 @@ ) where  import Language.PureScript.Names-import Language.PureScript.Declarations+import Language.PureScript.AST import Language.PureScript.Errors import Language.PureScript.Supply @@ -66,7 +66,7 @@   go (DoNotationBind binder val : rest) = do     rest' <- go rest     ident <- Ident <$> freshName-    return $ App (App bind val) (Abs (Left ident) (Case [Var (Qualified Nothing ident)] [CaseAlternative [binder] Nothing rest']))+    return $ App (App bind val) (Abs (Left ident) (Case [Var (Qualified Nothing ident)] [CaseAlternative [binder] (Right rest')]))   go [DoNotationLet _] = lift $ Left $ mkErrorStack "Let statement cannot be the last statement in a do block" Nothing   go (DoNotationLet ds : rest) = do     rest' <- go rest
src/Language/PureScript/Sugar/Names.hs view
@@ -4,7 +4,7 @@ -- Copyright   :  (c) 2013-14 Phil Freeman, (c) 2014 Gary Burgess, and other contributors -- License     :  MIT ----- Maintainer  :  Phil Freeman <paf31@cantab.net>+-- Maintainer  :  Phil Freeman <paf31@cantab.net>, Gary Burgess <gary.burgess@gmail.com> -- Stability   :  experimental -- Portability : --@@ -16,6 +16,7 @@   desugarImports ) where +import Data.List (nub) import Data.Maybe (fromMaybe, isJust, mapMaybe) import Data.Monoid ((<>)) @@ -24,7 +25,7 @@  import qualified Data.Map as M -import Language.PureScript.Declarations+import Language.PureScript.AST import Language.PureScript.Names import Language.PureScript.Types import Language.PureScript.Environment@@ -158,7 +159,7 @@       let env = M.update (\_ -> M.lookup mn unfilteredExports) mn exports       let exps = fromMaybe (error "Module is missing in renameInModule'") $ M.lookup mn exports       imports <- resolveImports env m-      renameInModule imports env (elaborateExports exps m)+      elaborateImports <$> renameInModule imports env (elaborateExports exps m)  -- | -- Make all exports for a module explicit. This may still effect modules that have an exports list,@@ -171,6 +172,23 @@   map ValueRef (exportedValues exps))  -- |+-- Add `import X ()` for any modules where there are only fully qualified references to members.+-- This ensures transitive instances are included when using a member from a module.+--+elaborateImports :: Module -> Module+elaborateImports (Module mn decls exps) = Module mn decls' exps+  where+  decls' :: [Declaration]+  decls' =+    let (f, _, _, _, _) = everythingOnValues (++) (const []) fqValues (const []) (const []) (const [])+    in mkImport `map` nub (f `concatMap` decls) ++ decls+  fqValues :: Expr -> [ModuleName]+  fqValues (Var (Qualified (Just mn') _)) = [mn']+  fqValues _ = []+  mkImport :: ModuleName -> Declaration+  mkImport mn' = ImportDeclaration mn' (Qualifying []) Nothing++-- | -- Replaces all local names with qualified names within a module and checks that all existing -- qualified names are valid. --@@ -222,10 +240,10 @@   updateBinder s v = return (s, v)    updateCase :: (Maybe SourcePos, [Ident]) -> CaseAlternative -> Either ErrorStack ((Maybe SourcePos, [Ident]), CaseAlternative)-  updateCase (pos, bound) c@(CaseAlternative bs _ _) = return ((pos, concatMap binderNames bs ++ bound), c)+  updateCase (pos, bound) c@(CaseAlternative bs _) = return ((pos, concatMap binderNames bs ++ bound), c)    letBoundVariable :: Declaration -> Maybe Ident-  letBoundVariable (ValueDeclaration ident _ _ _ _) = Just ident+  letBoundVariable (ValueDeclaration ident _ _ _) = Just ident   letBoundVariable (PositionedDeclaration _ d) = letBoundVariable d   letBoundVariable _ = Nothing @@ -304,7 +322,7 @@   addDecl mn env (DataDeclaration _ tn _ dcs) = addType env mn tn (map fst dcs)   addDecl mn env (TypeSynonymDeclaration tn _ _) = addType env mn tn []   addDecl mn env (ExternDataDeclaration tn _) = addType env mn tn []-  addDecl mn env (ValueDeclaration name _ _ _ _) = addValue env mn name+  addDecl mn env (ValueDeclaration name _ _ _) = addValue env mn name   addDecl mn env (ExternDeclaration _ name _ _) = addValue env mn name   addDecl mn env (PositionedDeclaration _ d) = addDecl mn env d   addDecl _  env _ = return env
src/Language/PureScript/Sugar/Operators.hs view
@@ -25,7 +25,7 @@ ) where  import Language.PureScript.Names-import Language.PureScript.Declarations+import Language.PureScript.AST import Language.PureScript.Errors  import Control.Applicative
src/Language/PureScript/Sugar/TypeClasses.hs view
@@ -18,7 +18,7 @@   desugarTypeClasses ) where -import Language.PureScript.Declarations+import Language.PureScript.AST import Language.PureScript.Names import Language.PureScript.Types import Language.PureScript.Kinds@@ -211,7 +211,7 @@  typeClassMemberToDictionaryAccessor :: ModuleName -> ProperName -> [(String, Maybe Kind)] -> Declaration -> Declaration typeClassMemberToDictionaryAccessor mn name args (TypeDeclaration ident ty) =-  ValueDeclaration ident TypeClassAccessorImport [] Nothing $+  ValueDeclaration ident TypeClassAccessorImport [] $ Right $     TypedValue False (Abs (Left $ Ident "dict") (Accessor (runIdent ident) (Var $ Qualified Nothing (Ident "dict")))) $     moveQuantifiersToFront (quantify (ConstrainedType [(Qualified (Just mn) name, map (TypeVar . fst) args)] ty)) typeClassMemberToDictionaryAccessor mn name args (PositionedDeclaration pos d) =@@ -258,19 +258,19 @@           dictTy = foldl TypeApp (TypeConstructor className) tys           constrainedTy = quantify (if null deps then dictTy else ConstrainedType deps dictTy)           dict = TypeClassDictionaryConstructorApp className memberNames'-          result = ValueDeclaration name TypeInstanceDictionaryValue [] Nothing (TypedValue True dict constrainedTy)+          result = ValueDeclaration name TypeInstanceDictionaryValue [] (Right (TypedValue True dict constrainedTy))       return result    where    declName :: Declaration -> Maybe Ident   declName (PositionedDeclaration _ d) = declName d-  declName (ValueDeclaration ident _ _ _ _) = Just ident+  declName (ValueDeclaration ident _ _ _) = Just ident   declName (TypeDeclaration ident _) = Just ident   declName _ = Nothing    memberToNameAndValue :: [(Ident, Type)] -> Declaration -> Desugar (Ident, Expr)-  memberToNameAndValue tys' d@(ValueDeclaration ident _ _ _ _) = do+  memberToNameAndValue tys' d@(ValueDeclaration ident _ _ _) = do     _ <- lift . lift . maybe (Left $ mkErrorStack ("Type class does not define member '" ++ show ident ++ "'") Nothing) Right $ lookup ident tys'     let memberValue = typeInstanceDictionaryEntryValue d     return (ident, memberValue)@@ -280,7 +280,7 @@   memberToNameAndValue _ _ = error "Invalid declaration in type instance definition"    typeInstanceDictionaryEntryValue :: Declaration -> Expr-  typeInstanceDictionaryEntryValue (ValueDeclaration _ _ [] _ val) = val+  typeInstanceDictionaryEntryValue (ValueDeclaration _ _ [] (Right val)) = val   typeInstanceDictionaryEntryValue (PositionedDeclaration pos d) = PositionedValue pos (typeInstanceDictionaryEntryValue d)   typeInstanceDictionaryEntryValue _ = error "Invalid declaration in type instance definition" 
src/Language/PureScript/Sugar/TypeDeclarations.hs view
@@ -25,10 +25,11 @@ import Control.Monad.Error.Class import Control.Monad (forM) -import Language.PureScript.Declarations+import Language.PureScript.AST import Language.PureScript.Names import Language.PureScript.Environment import Language.PureScript.Errors+import Language.PureScript.Traversals  -- | -- Replace all top level type declarations in a module with type annotations@@ -47,18 +48,20 @@   return (PositionedDeclaration pos d' : ds') desugarTypeDeclarations (TypeDeclaration name ty : d : rest) = do   (_, nameKind, val) <- fromValueDeclaration d-  desugarTypeDeclarations (ValueDeclaration name nameKind [] Nothing (TypedValue True val ty) : rest)+  desugarTypeDeclarations (ValueDeclaration name nameKind [] (Right (TypedValue True val ty)) : rest)   where   fromValueDeclaration :: Declaration -> Either ErrorStack (Ident, NameKind, Expr)-  fromValueDeclaration (ValueDeclaration name' nameKind [] Nothing val) | name == name' = return (name', nameKind, val)+  fromValueDeclaration (ValueDeclaration name' nameKind [] (Right val)) | name == name' = return (name', nameKind, val)   fromValueDeclaration (PositionedDeclaration pos d') = do     (ident, nameKind, val) <- rethrowWithPosition pos $ fromValueDeclaration d'     return (ident, nameKind, PositionedValue pos val)   fromValueDeclaration _ = throwError $ mkErrorStack ("Orphan type declaration for " ++ show name) Nothing desugarTypeDeclarations (TypeDeclaration name _ : []) = throwError $ mkErrorStack ("Orphan type declaration for " ++ show name) Nothing-desugarTypeDeclarations (ValueDeclaration name nameKind bs g val : rest) = do+desugarTypeDeclarations (ValueDeclaration name nameKind bs val : rest) = do   let (_, f, _) = everywhereOnValuesTopDownM return go return-  (:) <$> (ValueDeclaration name nameKind bs g <$> f val) <*> desugarTypeDeclarations rest+      f' (Left gs) = Left <$> mapM (pairM return f) gs+      f' (Right v) = Right <$> f v+  (:) <$> (ValueDeclaration name nameKind bs <$> f' val) <*> desugarTypeDeclarations rest   where   go (Let ds val') = Let <$> desugarTypeDeclarations ds <*> pure val'   go other = return other
src/Language/PureScript/Traversals.hs view
@@ -25,9 +25,16 @@ thirdM :: (Functor f) => (c -> f d) -> (a, b, c) -> f (a, b, d) thirdM f (a, b, c) = (,,) a b <$> f c +pairM :: (Applicative f) => (a -> f c) -> (b -> f d) -> (a, b) -> f (c, d)+pairM f g (a, b)  = (,) <$> f a <*> g b+ maybeM :: (Applicative f) => (a -> f b) -> Maybe a -> f (Maybe b) maybeM _ Nothing = pure Nothing maybeM f (Just a) = Just <$> f a++eitherM :: (Applicative f) => (a -> f c) -> (b -> f d) -> Either a b -> f (Either c d)+eitherM f _ (Left a)  = Left  <$> f a+eitherM _ g (Right b) = Right <$> g b  defS :: (Monad m) => st -> val -> m (st, val) defS s val = return (s, val)
src/Language/PureScript/TypeChecker.hs view
@@ -37,7 +37,7 @@ import Language.PureScript.Types import Language.PureScript.Names import Language.PureScript.Kinds-import Language.PureScript.Declarations+import Language.PureScript.AST import Language.PureScript.TypeClassDictionaries import Language.PureScript.Environment import Language.PureScript.Errors@@ -145,7 +145,7 @@       (syn_ks, data_ks) <- kindsOfAll moduleName syns (map (\(_, name, args, dctors) -> (name, args, concatMap snd dctors)) dataDecls)       forM_ (zip dataDecls data_ks) $ \((dtype, name, args, dctors), ctorKind) -> do         checkDuplicateTypeArguments $ map fst args-        let args' = args `withKinds` ctorKind +        let args' = args `withKinds` ctorKind         addDataType moduleName dtype name args' dctors ctorKind       forM_ (zip syns syn_ks) $ \((name, args, ty), kind) -> do         checkDuplicateTypeArguments $ map fst args@@ -169,12 +169,12 @@     ds <- go rest     return $ TypeSynonymDeclaration name args ty : ds   go (TypeDeclaration _ _ : _) = error "Type declarations should have been removed"-  go (ValueDeclaration name nameKind [] Nothing val : rest) = do+  go (ValueDeclaration name nameKind [] (Right val) : rest) = do     d <- rethrow (strMsg ("Error in declaration " ++ show name) <>) $ do       valueIsNotDefined moduleName name       [(_, (val', ty))] <- typesOf mainModuleName moduleName [(name, val)]       addValue moduleName name ty nameKind-      return $ ValueDeclaration name nameKind [] Nothing val'+      return $ ValueDeclaration name nameKind [] $ Right val'     ds <- go rest     return $ d : ds   go (ValueDeclaration{} : _) = error "Binders were not desugared"@@ -183,10 +183,10 @@       forM_ (map (\(ident, _, _) -> ident) vals) $ \name ->         valueIsNotDefined moduleName name       tys <- typesOf mainModuleName moduleName $ map (\(ident, _, ty) -> (ident, ty)) vals-      vals' <- forM [ (name, val, nameKind, ty) +      vals' <- forM [ (name, val, nameKind, ty)                     | (name, nameKind, _) <- vals                     , (name', (val, ty)) <- tys-                    , name == name' +                    , name == name'                     ] $ \(name, val, nameKind, ty) -> do         addValue moduleName name ty nameKind         return (name, nameKind, val)@@ -248,9 +248,9 @@     rethrowWithPosition pos $ do       (d' : rest') <- go (d : rest)       return (PositionedDeclaration pos d' : rest')-  +   -- |-  -- This function adds the argument kinds for a type constructor so that they may appear in the externs file, +  -- This function adds the argument kinds for a type constructor so that they may appear in the externs file,   -- extracted from the kind of the type constructor itself.   --   withKinds :: [(String, Maybe Kind)] -> Kind -> [(String, Maybe Kind)]
+ src/Language/PureScript/TypeChecker/Entailment.hs view
@@ -0,0 +1,217 @@+-----------------------------------------------------------------------------+--+-- Module      :  Language.PureScript.TypeChecker.Entailment+-- Copyright   :  (c) Phil Freeman 2013+-- License     :  MIT+--+-- Maintainer  :  Phil Freeman <paf31@cantab.net>+-- Stability   :  experimental+-- Portability :+--+-- |+-- Type class entailment+--+-----------------------------------------------------------------------------++module Language.PureScript.TypeChecker.Entailment (+    entails+) where++import Data.Function (on)+import Data.List+import Data.Maybe (maybeToList)+import qualified Data.Map as M++import Control.Applicative+import Control.Arrow (Arrow(..))+import Control.Monad.Error++import Language.PureScript.AST+import Language.PureScript.Environment+import Language.PureScript.Names+import Language.PureScript.Pretty+import Language.PureScript.TypeChecker.Monad+import Language.PureScript.TypeChecker.Synonyms+import Language.PureScript.TypeChecker.Unify+import Language.PureScript.TypeClassDictionaries+import Language.PureScript.Types+import qualified Language.PureScript.Constants as C++-- |+-- A simplified representation of expressions which are used to represent type+-- class dictionaries at runtime, which can be compared for equality+--+data DictionaryValue+  -- |+  -- A dictionary which is brought into scope by a local constraint+  --+  = LocalDictionaryValue (Qualified Ident)+  -- |+  -- A dictionary which is brought into scope by an instance declaration+  --+  | GlobalDictionaryValue (Qualified Ident)+  -- |+  -- A dictionary which depends on other dictionaries+  --+  | DependentDictionaryValue (Qualified Ident) [DictionaryValue]+  -- |+  -- A subclass dictionary+  --+  | SubclassDictionaryValue DictionaryValue (Qualified ProperName) Integer+  deriving (Show, Ord, Eq)++-- |+-- Check that the current set of type class dictionaries entail the specified type class goal, and, if so,+-- return a type class dictionary reference.+--+entails :: Environment -> ModuleName -> [TypeClassDictionaryInScope] -> (Qualified ProperName, [Type]) -> Bool -> Check Expr+entails env moduleName context = solve (sortedNubBy canonicalizeDictionary (filter filterModule context))+  where+    sortedNubBy :: (Ord k) => (v -> k) -> [v] -> [v]+    sortedNubBy f vs = M.elems (M.fromList (map (f &&& id) vs))++    -- Filter out type dictionaries which are in scope in the current module+    filterModule :: TypeClassDictionaryInScope -> Bool+    filterModule (TypeClassDictionaryInScope { tcdName = Qualified (Just mn) _ }) | mn == moduleName = True+    filterModule (TypeClassDictionaryInScope { tcdName = Qualified Nothing _ }) = True+    filterModule _ = False++    solve context' (className, tys) trySuperclasses =+      checkOverlaps $ go trySuperclasses className tys+      where+      go trySuperclasses' className' tys' =+        -- Look for regular type instances+        [ mkDictionary (canonicalizeDictionary tcd) args+        | tcd <- context'+        -- Make sure the type class name matches the one we are trying to satisfy+        , className' == tcdClassName tcd+        -- Make sure the type unifies with the type in the type instance definition+        , subst <- maybeToList . (>>= verifySubstitution) . fmap concat $ zipWithM (typeHeadsAreEqual moduleName env) tys' (tcdInstanceTypes tcd)+        -- Solve any necessary subgoals+        , args <- solveSubgoals subst (tcdDependencies tcd) ] ++++        -- Look for implementations via superclasses+        [ SubclassDictionaryValue suDict superclass index+        | trySuperclasses'+        , (subclassName, (args, _, implies)) <- M.toList (typeClasses env)+        -- Try each superclass+        , (index, (superclass, suTyArgs)) <- zip [0..] implies+        -- Make sure the type class name matches the superclass name+        , className' == superclass+        -- Make sure the types unify with the types in the superclass implication+        , subst <- maybeToList . (>>= verifySubstitution) . fmap concat $ zipWithM (typeHeadsAreEqual moduleName env) tys' suTyArgs+        -- Finally, satisfy the subclass constraint+        , args' <- maybeToList $ mapM ((`lookup` subst) . fst) args+        , suDict <- go True subclassName args' ]++      -- Create dictionaries for subgoals which still need to be solved by calling go recursively+      -- E.g. the goal (Show a, Show b) => Show (Either a b) can be satisfied if the current type+      -- unifies with Either a b, and we can satisfy the subgoals Show a and Show b recursively.+      solveSubgoals :: [(String, Type)] -> Maybe [(Qualified ProperName, [Type])] -> [Maybe [DictionaryValue]]+      solveSubgoals _ Nothing = return Nothing+      solveSubgoals subst (Just subgoals) = do+        dict <- mapM (uncurry (go True) . second (map (replaceAllTypeVars subst))) subgoals+        return $ Just dict+      -- Make a dictionary from subgoal dictionaries by applying the correct function+      mkDictionary :: Qualified Ident -> Maybe [DictionaryValue] -> DictionaryValue+      mkDictionary fnName Nothing = LocalDictionaryValue fnName+      mkDictionary fnName (Just []) = GlobalDictionaryValue fnName+      mkDictionary fnName (Just dicts) = DependentDictionaryValue fnName dicts+      -- Turn a DictionaryValue into a Expr+      dictionaryValueToValue :: DictionaryValue -> Expr+      dictionaryValueToValue (LocalDictionaryValue fnName) = Var fnName+      dictionaryValueToValue (GlobalDictionaryValue fnName) = Var fnName+      dictionaryValueToValue (DependentDictionaryValue fnName dicts) = foldl App (Var fnName) (map dictionaryValueToValue dicts)+      dictionaryValueToValue (SubclassDictionaryValue dict superclassName index) =+        App (Accessor (C.__superclass_ ++ show superclassName ++ "_" ++ show index)+                      (dictionaryValueToValue dict))+            valUndefined+      -- Ensure that a substitution is valid+      verifySubstitution :: [(String, Type)] -> Maybe [(String, Type)]+      verifySubstitution subst = do+        let grps = groupBy ((==) `on` fst) subst+        guard (all (pairwise (unifiesWith env) . map snd) grps)+        return $ map head grps+      -- |+      -- Check for overlapping instances+      --+      checkOverlaps :: [DictionaryValue] -> Check Expr+      checkOverlaps dicts =+        case [ (d1, d2) | d1 <- dicts, d2 <- dicts, d1 `overlapping` d2 ] of+          (d1, d2) : _ -> throwError . strMsg $ unlines+            [ "Overlapping instances found for " ++ show className ++ " " ++ unwords (map prettyPrintType tys) ++ "."+            , "For example:"+            , prettyPrintDictionaryValue d1+            , "and:"+            , prettyPrintDictionaryValue d2+            ]+          _ -> case chooseSimplestDictionaries dicts of+                 [] -> throwError . strMsg $+                         "No instance found for " ++ show className ++ " " ++ unwords (map prettyPrintTypeAtom tys)+                 d : _ -> return $ dictionaryValueToValue d+      -- Choose the simplest DictionaryValues from a list of candidates+      -- The reason for this function is as follows:+      -- When considering overlapping instances, we don't want to consider the same dictionary+      -- to be an overlap of itself when obtained as a superclass of another class.+      -- Observing that we probably don't want to select a superclass instance when an instance+      -- is available directly, and that there is no way for a superclass instance to actually+      -- introduce an overlap that wouldn't have been there already, we simply remove dictionaries+      -- obtained as superclass instances if there are simpler instances available.+      chooseSimplestDictionaries :: [DictionaryValue] -> [DictionaryValue]+      chooseSimplestDictionaries ds = case filter isSimpleDictionaryValue ds of+                                        [] -> ds+                                        simple -> simple+      isSimpleDictionaryValue SubclassDictionaryValue{} = False+      isSimpleDictionaryValue (DependentDictionaryValue _ ds) = all isSimpleDictionaryValue ds+      isSimpleDictionaryValue _ = True+      -- |+      -- Check if two dictionaries are overlapping+      --+      -- Dictionaries which are subclass dictionaries cannot overlap, since otherwise the overlap would have+      -- been caught when constructing superclass dictionaries.+      --+      overlapping :: DictionaryValue -> DictionaryValue -> Bool+      overlapping (LocalDictionaryValue nm1)         (LocalDictionaryValue nm2)  | nm1 == nm2 = False+      overlapping (GlobalDictionaryValue nm1)        (GlobalDictionaryValue nm2) | nm1 == nm2 = False+      overlapping (DependentDictionaryValue nm1 ds1) (DependentDictionaryValue nm2 ds2)+        | nm1 == nm2 = or $ zipWith overlapping ds1 ds2+      overlapping SubclassDictionaryValue{} _ = False+      overlapping _ SubclassDictionaryValue{} = False+      overlapping _ _ = True+      -- |+      -- Render a DictionaryValue fit for human consumption in error messages+      --+      prettyPrintDictionaryValue :: DictionaryValue -> String+      prettyPrintDictionaryValue = unlines . indented 0+        where+        indented n (LocalDictionaryValue _)           = [spaces n ++ "Dictionary in scope"]+        indented n (GlobalDictionaryValue nm)         = [spaces n ++ show nm]+        indented n (DependentDictionaryValue nm args) = (spaces n ++ show nm ++ " via") : concatMap (indented (n + 2)) args+        indented n (SubclassDictionaryValue sup nm _) = (spaces n ++ show nm ++ " via superclass") : indented (n + 2) sup++        spaces n = replicate n ' ' ++ "- "++    valUndefined :: Expr+    valUndefined = Var (Qualified (Just (ModuleName [ProperName C.prim])) (Ident C.undefined))++-- |+-- Check whether the type heads of two types are equal (for the purposes of type class dictionary lookup),+-- and return a substitution from type variables to types which makes the type heads unify.+--+typeHeadsAreEqual :: ModuleName -> Environment -> Type -> Type -> Maybe [(String, Type)]+typeHeadsAreEqual _ _ (Skolem _ s1 _) (Skolem _ s2 _) | s1 == s2 = Just []+typeHeadsAreEqual _ _ t (TypeVar v) = Just [(v, t)]+typeHeadsAreEqual _ _ (TypeConstructor c1) (TypeConstructor c2) | c1 == c2 = Just []+typeHeadsAreEqual m e (TypeApp h1 t1) (TypeApp h2 t2) = (++) <$> typeHeadsAreEqual m e h1 h2 <*> typeHeadsAreEqual m e t1 t2+typeHeadsAreEqual m e (SaturatedTypeSynonym name args) t2 = case expandTypeSynonym' e name args of+  Left  _  -> Nothing+  Right t1 -> typeHeadsAreEqual m e t1 t2+typeHeadsAreEqual _ _ _ _ = Nothing++-- |+-- Check all values in a list pairwise match a predicate+--+pairwise :: (a -> a -> Bool) -> [a] -> Bool+pairwise _ [] = True+pairwise _ [_] = True+pairwise p (x : xs) = all (p x) xs && pairwise p xs
src/Language/PureScript/TypeChecker/Kinds.hs view
@@ -22,23 +22,23 @@     kindsOfAll ) where -import Language.PureScript.Types-import Language.PureScript.Kinds-import Language.PureScript.Names-import Language.PureScript.TypeChecker.Monad-import Language.PureScript.Pretty-import Language.PureScript.Environment-import Language.PureScript.Errors+import Data.Maybe (fromMaybe)+import Data.Monoid ((<>))+import qualified Data.HashMap.Strict as H+import qualified Data.Map as M -import Control.Monad.State+import Control.Applicative import Control.Monad.Error+import Control.Monad.State import Control.Monad.Unify -import Control.Applicative--import qualified Data.Map as M-import qualified Data.HashMap.Strict as H-import Data.Monoid ((<>))+import Language.PureScript.Environment+import Language.PureScript.Errors+import Language.PureScript.Kinds+import Language.PureScript.Names+import Language.PureScript.Pretty+import Language.PureScript.TypeChecker.Monad+import Language.PureScript.Types  instance Partial Kind where   unknown = KUnknown@@ -50,9 +50,7 @@     go _ = []   ($?) sub = everywhereOnKinds go     where-    go t@(KUnknown u) = case H.lookup u (runSubstitution sub) of-                          Nothing -> t-                          Just t' -> t'+    go t@(KUnknown u) = fromMaybe t $ H.lookup u (runSubstitution sub)     go other = other  instance Unifiable Check Kind where@@ -85,12 +83,12 @@   tyCon <- fresh   kargs <- replicateM (length args) fresh   rest <- zipWithM freshKindVar args kargs-  let dict = (name, tyCon) : rest +  let dict = (name, tyCon) : rest   bindLocalTypeVariables moduleName dict $     solveTypes isData ts kargs tyCon   where   tidyUp (k, sub) = starIfUnknown $ sub $? k-  + freshKindVar :: (String, Maybe Kind) -> Kind -> UnifyT Kind Check (ProperName, Kind) freshKindVar (arg, Nothing) kind = return (ProperName arg, kind) freshKindVar (arg, Just kind') kind = do@@ -125,13 +123,13 @@ -- | -- Solve the set of kind constraints associated with the data constructors for a type constructor ---solveTypes :: Bool -> [Type] -> [Kind] -> Kind -> UnifyT Kind (Check) Kind+solveTypes :: Bool -> [Type] -> [Kind] -> Kind -> UnifyT Kind Check Kind solveTypes isData ts kargs tyCon = do   ks <- mapM infer ts   when isData $ do     tyCon =?= foldr FunKind Star kargs     forM_ ks $ \k -> k =?= Star-  when (not isData) $ do+  unless isData $     tyCon =?= foldr FunKind (head ks) kargs   return tyCon @@ -151,6 +149,7 @@ infer ty = rethrow (mkErrorStack "Error inferring type of value" (Just (TypeError ty)) <>) $ infer' ty  infer' :: Type -> UnifyT Kind Check Kind+infer' TypeWildcard = fresh infer' (TypeVar v) = do   Just moduleName <- checkCurrentModule <$> get   UnifyT . lift $ lookupTypeVariable moduleName (Qualified Nothing (ProperName v))@@ -191,6 +190,3 @@   k =?= k'   return k' infer' _ = error "Invalid argument to infer"---
src/Language/PureScript/TypeChecker/Monad.hs view
@@ -18,23 +18,21 @@  module Language.PureScript.TypeChecker.Monad where -import Language.PureScript.Types-import Language.PureScript.Kinds-import Language.PureScript.Names-import Language.PureScript.Declarations (canonicalizeDictionary)-import Language.PureScript.Environment-import Language.PureScript.TypeClassDictionaries-import Language.PureScript.Options-import Language.PureScript.Errors- import Data.Maybe+import qualified Data.Map as M  import Control.Applicative-import Control.Monad.State import Control.Monad.Error+import Control.Monad.State import Control.Monad.Unify -import qualified Data.Map as M+import Language.PureScript.Environment+import Language.PureScript.Errors+import Language.PureScript.Kinds+import Language.PureScript.Names+import Language.PureScript.Options+import Language.PureScript.TypeClassDictionaries+import Language.PureScript.Types  -- | -- Temporarily bind a collection of names to values
+ src/Language/PureScript/TypeChecker/Rows.hs view
@@ -0,0 +1,66 @@+-----------------------------------------------------------------------------+--+-- Module      :  Language.PureScript.TypeChecker.Rows+-- Copyright   :  (c) Phil Freeman 2013+-- License     :  MIT+--+-- Maintainer  :  Phil Freeman <paf31@cantab.net>+-- Stability   :  experimental+-- Portability :+--+-- |+-- Functions relating to type checking for rows+--+-----------------------------------------------------------------------------++module Language.PureScript.TypeChecker.Rows (+    checkDuplicateLabels+) where++import Data.List++import Control.Monad.Error++import Language.PureScript.AST+import Language.PureScript.Errors+import Language.PureScript.TypeChecker.Monad+import Language.PureScript.Types++-- |+-- Ensure rows do not contain duplicate labels+--+checkDuplicateLabels :: Expr -> Check ()+checkDuplicateLabels =+  let (_, f, _) = everywhereOnValuesM def go def+  in void . f+  where+  def :: a -> Check a+  def = return++  go :: Expr -> Check Expr+  go e@(TypedValue _ val ty) = do+    checkDups ty+    return e++    where+    checkDups :: Type -> Check ()+    checkDups (TypeApp t1 t2) = checkDups t1 >> checkDups t2+    checkDups (SaturatedTypeSynonym _ ts) = mapM_ checkDups ts+    checkDups (ForAll _ t _) = checkDups t+    checkDups (ConstrainedType args t) = do+      mapM_ checkDups $ concatMap snd args+      checkDups t+    checkDups r@RCons{} =+      let (ls, _) = rowToList r in+      case firstDup . sort . map fst $ ls of+        Just l -> throwError $ mkErrorStack ("Duplicate label " ++ show l ++ " in row") $ Just (ExprError val)+        Nothing -> return ()+    checkDups _ = return ()++    firstDup :: (Eq a) => [a] -> Maybe a+    firstDup (x : xs@(x' : _))+      | x == x' = Just x+      | otherwise = firstDup xs+    firstDup _ = Nothing++  go other = return other
+ src/Language/PureScript/TypeChecker/Skolems.hs view
@@ -0,0 +1,114 @@+-----------------------------------------------------------------------------+--+-- Module      :  Language.PureScript.TypeChecker.Skolems+-- Copyright   :  (c) Phil Freeman 2013+-- License     :  MIT+--+-- Maintainer  :  Phil Freeman <paf31@cantab.net>+-- Stability   :  experimental+-- Portability :+--+-- |+-- Functions relating to skolemization used during typechecking+--+-----------------------------------------------------------------------------++module Language.PureScript.TypeChecker.Skolems (+    newSkolemConstant,+    introduceSkolemScope,+    newSkolemScope,+    skolemize,+    skolemizeTypesInValue,+    skolemEscapeCheck+) where++import Data.List (nub, (\\))+import Data.Monoid++import Control.Applicative+import Control.Monad.Error+import Control.Monad.Unify++import Language.PureScript.AST+import Language.PureScript.Errors+import Language.PureScript.Pretty+import Language.PureScript.TypeChecker.Monad+import Language.PureScript.Types++-- |+-- Generate a new skolem constant+--+newSkolemConstant :: UnifyT Type Check Int+newSkolemConstant = fresh'++-- |+-- Introduce skolem scope at every occurence of a ForAll+--+introduceSkolemScope :: Type -> UnifyT Type Check Type+introduceSkolemScope = everywhereOnTypesM go+  where+  go (ForAll ident ty Nothing) = ForAll ident ty <$> (Just <$> newSkolemScope)+  go other = return other++-- |+-- Generate a new skolem scope+--+newSkolemScope :: UnifyT Type Check SkolemScope+newSkolemScope = SkolemScope <$> fresh'++-- |+-- Skolemize a type variable by replacing its instances with fresh skolem constants+--+skolemize :: String -> Int -> SkolemScope -> Type -> Type+skolemize ident sko scope = replaceTypeVars ident (Skolem ident sko scope)++-- |+-- This function has one purpose - to skolemize type variables appearing in a+-- SuperClassDictionary placeholder. These type variables are somewhat unique since they are the+-- only example of scoped type variables.+--+skolemizeTypesInValue :: String -> Int -> SkolemScope -> Expr -> Expr+skolemizeTypesInValue ident sko scope = let (_, f, _) = everywhereOnValues id go id in f+  where+  go (SuperClassDictionary c ts) = SuperClassDictionary c (map (skolemize ident sko scope) ts)+  go other = other++-- |+-- Ensure skolem variables do not escape their scope+--+skolemEscapeCheck :: Expr -> Check ()+skolemEscapeCheck (TypedValue False _ _) = return ()+skolemEscapeCheck root@TypedValue{} =+  -- Every skolem variable is created when a ForAll type is skolemized.+  -- This determines the scope of that skolem variable, which is copied from the SkolemScope+  -- field of the ForAll constructor.+  -- We traverse the tree top-down, and collect any SkolemScopes introduced by ForAlls.+  -- If a Skolem is encountered whose SkolemScope is not in the current list, we have found+  -- an escaped skolem variable.+  let (_, f, _, _, _) = everythingWithContextOnValues [] [] (++) def go def def def+  in case f root of+       [] -> return ()+       ((binding, val) : _) -> throwError $ mkErrorStack ("Rigid/skolem type variable " ++ maybe "" (("bound by " ++) . prettyPrintValue) binding ++ " has escaped.") (Just (ExprError val))+  where+  def s _ = (s, [])++  go :: [(SkolemScope, Expr)] -> Expr -> ([(SkolemScope, Expr)], [(Maybe Expr, Expr)])+  go scos val@(TypedValue _ _ (ForAll _ _ (Just sco))) = ((sco, val) : scos, [])+  go scos val@(TypedValue _ _ ty) = case collectSkolems ty \\ map fst scos of+                                      (sco : _) -> (scos, [(findBindingScope sco, val)])+                                      _ -> (scos, [])+    where+    collectSkolems :: Type -> [SkolemScope]+    collectSkolems = nub . everythingOnTypes (++) collect+      where+      collect (Skolem _ _ scope) = [scope]+      collect _ = []+  go scos _ = (scos, [])+  findBindingScope :: SkolemScope -> Maybe Expr+  findBindingScope sco =+    let (_, f, _, _, _) = everythingOnValues mappend (const mempty) go' (const mempty) (const mempty) (const mempty)+    in getFirst $ f root+    where+    go' val@(TypedValue _ _ (ForAll _ _ (Just sco'))) | sco == sco' = First (Just val)+    go' _ = mempty+skolemEscapeCheck val = throwError $ mkErrorStack "Untyped value passed to skolemEscapeCheck" (Just (ExprError val))
+ src/Language/PureScript/TypeChecker/Subsumption.hs view
@@ -0,0 +1,103 @@+-----------------------------------------------------------------------------+--+-- Module      :  Language.PureScript.TypeChecker.Subsumption+-- Copyright   :  (c) Phil Freeman 2013+-- License     :  MIT+--+-- Maintainer  :  Phil Freeman <paf31@cantab.net>+-- Stability   :  experimental+-- Portability :+--+-- |+-- Subsumption checking+--+-----------------------------------------------------------------------------++module Language.PureScript.TypeChecker.Subsumption (+    subsumes+) where++import Data.List (sortBy)+import Data.Monoid+import Data.Ord (comparing)++import Control.Applicative+import Control.Monad.Error+import Control.Monad.Unify++import Language.PureScript.AST+import Language.PureScript.Environment+import Language.PureScript.Errors+import Language.PureScript.Pretty+import Language.PureScript.TypeChecker.Monad+import Language.PureScript.TypeChecker.Skolems+import Language.PureScript.TypeChecker.Synonyms+import Language.PureScript.TypeChecker.Unify+import Language.PureScript.Types++-- |+-- Check whether one type subsumes another, rethrowing errors to provide a better error message+--+subsumes :: Maybe Expr -> Type -> Type -> UnifyT Type Check (Maybe Expr)+subsumes val ty1 ty2 = rethrow (mkErrorStack errorMessage (ExprError <$> val) <>) $ subsumes' val ty1 ty2+  where+  errorMessage = "Error checking that type "+    ++ prettyPrintType ty1+    ++ " subsumes type "+    ++ prettyPrintType ty2++-- |+-- Check whether one type subsumes another+--+subsumes' :: Maybe Expr -> Type -> Type -> UnifyT Type Check (Maybe Expr)+subsumes' val (ForAll ident ty1 _) ty2 = do+  replaced <- replaceVarWithUnknown ident ty1+  subsumes val replaced ty2+subsumes' val ty1 (ForAll ident ty2 sco) =+  case sco of+    Just sco' -> do+      sko <- newSkolemConstant+      let sk = skolemize ident sko sco' ty2+      subsumes val ty1 sk+    Nothing -> throwError . strMsg $ "Skolem variable scope is unspecified"+subsumes' val (TypeApp (TypeApp f1 arg1) ret1) (TypeApp (TypeApp f2 arg2) ret2) | f1 == tyFunction && f2 == tyFunction = do+  _ <- subsumes Nothing arg2 arg1+  _ <- subsumes Nothing ret1 ret2+  return val+subsumes' val (SaturatedTypeSynonym name tyArgs) ty2 = do+  ty1 <- introduceSkolemScope <=< expandTypeSynonym name $ tyArgs+  subsumes val ty1 ty2+subsumes' val ty1 (SaturatedTypeSynonym name tyArgs) = do+  ty2 <- introduceSkolemScope <=< expandTypeSynonym name $ tyArgs+  subsumes val ty1 ty2+subsumes' val (KindedType ty1 _) ty2 =+  subsumes val ty1 ty2+subsumes' val ty1 (KindedType ty2 _) =+  subsumes val ty1 ty2+subsumes' (Just val) (ConstrainedType constraints ty1) ty2 = do+  dicts <- getTypeClassDictionaries+  subsumes' (Just $ foldl App val (map (flip (TypeClassDictionary True) dicts) constraints)) ty1 ty2+subsumes' val (TypeApp f1 r1) (TypeApp f2 r2) | f1 == tyObject && f2 == tyObject = do+  let+    (ts1, r1') = rowToList r1+    (ts2, r2') = rowToList r2+    ts1' = sortBy (comparing fst) ts1+    ts2' = sortBy (comparing fst) ts2+  go ts1' ts2' r1' r2'+  return val+  where+  go [] ts2 r1' r2' = r1' =?= rowFromList (ts2, r2')+  go ts1 [] r1' r2' = r2' =?= rowFromList (ts1, r1')+  go ((p1, ty1) : ts1) ((p2, ty2) : ts2) r1' r2'+    | p1 == p2 = do _ <- subsumes Nothing ty1 ty2+                    go ts1 ts2 r1' r2'+    | p1 < p2 = do rest <- fresh+                   r2' =?= RCons p1 ty1 rest+                   go ts1 ((p2, ty2) : ts2) r1' rest+    | otherwise = do rest <- fresh+                     r1' =?= RCons p2 ty2 rest+                     go ((p1, ty1) : ts1) ts2 rest r2'+subsumes' val ty1 ty2@(TypeApp obj _) | obj == tyObject = subsumes val ty2 ty1+subsumes' val ty1 ty2 = do+  ty1 =?= ty2+  return val
src/Language/PureScript/TypeChecker/Synonyms.hs view
@@ -13,18 +13,29 @@ -- ----------------------------------------------------------------------------- +{-# LANGUAGE FlexibleContexts, MultiParamTypeClasses #-}+ module Language.PureScript.TypeChecker.Synonyms (-    saturateAllTypeSynonyms+    saturateAllTypeSynonyms,+    desaturateAllTypeSynonyms,+    replaceAllTypeSynonyms,+    expandAllTypeSynonyms,+    expandTypeSynonym,+    expandTypeSynonym' ) where -import Language.PureScript.Types-import Language.PureScript.Names--import Control.Applicative ((<$>)) import Data.Maybe (fromMaybe)-import Control.Monad.Writer+import qualified Data.Map as M++import Control.Applicative import Control.Monad.Error+import Control.Monad.State +import Language.PureScript.Environment+import Language.PureScript.Names+import Language.PureScript.TypeChecker.Monad+import Language.PureScript.Types+ -- | -- Build a type substitution for a type synonym --@@ -51,5 +62,49 @@ saturateAllTypeSynonyms :: [(Qualified ProperName, Int)] -> Type -> Either String Type saturateAllTypeSynonyms syns d = foldM (\result (name, n) -> saturateTypeSynonym name n result) d syns +-- |+-- \"Desaturate\" @SaturatedTypeSynonym@s+--+desaturateAllTypeSynonyms :: Type -> Type+desaturateAllTypeSynonyms = everywhereOnTypes replaceSaturatedTypeSynonym+  where+  replaceSaturatedTypeSynonym (SaturatedTypeSynonym name args) = foldl TypeApp (TypeConstructor name) args+  replaceSaturatedTypeSynonym t = t +-- |+-- Replace fully applied type synonyms with the @SaturatedTypeSynonym@ data constructor, which helps generate+-- better error messages during unification.+--+replaceAllTypeSynonyms' :: Environment -> Type -> Either String Type+replaceAllTypeSynonyms' env d =+  let+    syns = map (\(name, (args, _)) -> (name, length args)) . M.toList $ typeSynonyms env+  in+    saturateAllTypeSynonyms syns d +replaceAllTypeSynonyms :: (Error e, Functor m, Monad m, MonadState CheckState m, MonadError e m) => Type -> m Type+replaceAllTypeSynonyms d = do+  env <- getEnv+  either (throwError . strMsg) return $ replaceAllTypeSynonyms' env d++-- |+-- Replace a type synonym and its arguments with the aliased type+--+expandTypeSynonym' :: Environment -> Qualified ProperName -> [Type] -> Either String Type+expandTypeSynonym' env name args =+  case M.lookup name (typeSynonyms env) of+    Just (synArgs, body) -> do+      let repl = replaceAllTypeVars (zip (map fst synArgs) args) body+      replaceAllTypeSynonyms' env repl+    Nothing -> error "Type synonym was not defined"++expandTypeSynonym :: (Error e, Functor m, Monad m, MonadState CheckState m, MonadError e m) => Qualified ProperName -> [Type] -> m Type+expandTypeSynonym name args = do+  env <- getEnv+  either (throwError . strMsg) return $ expandTypeSynonym' env name args++expandAllTypeSynonyms :: (Error e, Functor m, Applicative m, Monad m, MonadState CheckState m, MonadError e m) => Type -> m Type+expandAllTypeSynonyms = everywhereOnTypesTopDownM go+  where+  go (SaturatedTypeSynonym name args) = expandTypeSynonym name args+  go other = return other
src/Language/PureScript/TypeChecker/Types.hs view
@@ -13,10 +13,7 @@ -- ----------------------------------------------------------------------------- -{-# OPTIONS_GHC -fno-warn-orphans #-}-{-# LANGUAGE FlexibleInstances #-}-{-# LANGUAGE FlexibleContexts #-}-{-# LANGUAGE MultiParamTypeClasses #-}+{-# LANGUAGE FlexibleContexts, MultiParamTypeClasses #-}  module Language.PureScript.TypeChecker.Types (     typesOf@@ -36,138 +33,38 @@      checkFunctionApplication       Check a function of a given type returns a value of another type when applied to its arguments--    subsumes-      Check a type subsumes another type -} +import Data.Either (lefts, rights) import Data.List-import Data.Maybe (maybeToList, fromMaybe)-import Data.Function (on)-import Data.Ord (comparing)+import Data.Maybe (fromMaybe) import Data.Monoid-import Data.Either (lefts, rights)+import qualified Data.Map as M -import Language.PureScript.Declarations-import Language.PureScript.Types+import Control.Applicative+import Control.Monad.Error+import Control.Monad.State+import Control.Monad.Unify++import Language.PureScript.AST+import Language.PureScript.Environment+import Language.PureScript.Errors import Language.PureScript.Kinds import Language.PureScript.Names-import Language.PureScript.TypeClassDictionaries-import Language.PureScript.TypeChecker.Monad+import Language.PureScript.Pretty+import Language.PureScript.TypeChecker.Entailment import Language.PureScript.TypeChecker.Kinds+import Language.PureScript.TypeChecker.Monad+import Language.PureScript.TypeChecker.Rows+import Language.PureScript.TypeChecker.Skolems+import Language.PureScript.TypeChecker.Subsumption import Language.PureScript.TypeChecker.Synonyms-import Language.PureScript.Pretty-import Language.PureScript.Environment-import Language.PureScript.Errors+import Language.PureScript.TypeChecker.Unify+import Language.PureScript.TypeClassDictionaries+import Language.PureScript.Types import qualified Language.PureScript.Constants as C -import Control.Monad.State-import Control.Monad.Error-import Control.Monad.Unify--import Control.Applicative-import Control.Arrow (Arrow(..))--import qualified Data.Map as M-import qualified Data.HashMap.Strict as H--instance Partial Type where-  unknown = TUnknown-  isUnknown (TUnknown u) = Just u-  isUnknown _ = Nothing-  unknowns = everythingOnTypes (++) go-    where-    go (TUnknown u) = [u]-    go _ = []-  ($?) sub = everywhereOnTypes go-    where-    go t@(TUnknown u) = case H.lookup u (runSubstitution sub) of-                          Nothing -> t-                          Just t' -> t'-    go other = other--instance Unifiable Check Type where-  (=?=) = unifyTypes- -- |--- Unify two types, updating the current substitution----unifyTypes :: Type -> Type -> UnifyT Type Check ()-unifyTypes t1 t2 = rethrow (mkErrorStack ("Error unifying type " ++ prettyPrintType t1 ++ " with type " ++ prettyPrintType t2) Nothing <>) $-  unifyTypes' t1 t2-  where-  unifyTypes' (TUnknown u1) (TUnknown u2) | u1 == u2 = return ()-  unifyTypes' (TUnknown u) t = u =:= t-  unifyTypes' t (TUnknown u) = u =:= t-  unifyTypes' (SaturatedTypeSynonym name args) ty = do-    ty1 <- introduceSkolemScope <=< expandTypeSynonym name $ args-    ty1 `unifyTypes` ty-  unifyTypes' ty s@(SaturatedTypeSynonym _ _) = s `unifyTypes` ty-  unifyTypes' (ForAll ident1 ty1 sc1) (ForAll ident2 ty2 sc2) =-    case (sc1, sc2) of-      (Just sc1', Just sc2') -> do-        sko <- newSkolemConstant-        let sk1 = skolemize ident1 sko sc1' ty1-        let sk2 = skolemize ident2 sko sc2' ty2-        sk1 `unifyTypes` sk2-      _ -> error "Skolemized type variable was not given a scope"-  unifyTypes' (ForAll ident ty1 (Just sc)) ty2 = do-    sko <- newSkolemConstant-    let sk = skolemize ident sko sc ty1-    sk `unifyTypes` ty2-  unifyTypes' ForAll{} _ = throwError . strMsg $ "Skolem variable scope is unspecified"-  unifyTypes' ty f@ForAll{} = f `unifyTypes` ty-  unifyTypes' (TypeVar v1) (TypeVar v2) | v1 == v2 = return ()-  unifyTypes' (TypeConstructor c1) (TypeConstructor c2) =-    guardWith (strMsg ("Cannot unify " ++ show c1 ++ " with " ++ show c2 ++ ".")) (c1 == c2)-  unifyTypes' (TypeApp t3 t4) (TypeApp t5 t6) = do-    t3 `unifyTypes` t5-    t4 `unifyTypes` t6-  unifyTypes' (Skolem _ s1 _) (Skolem _ s2 _) | s1 == s2 = return ()-  unifyTypes' (KindedType ty1 _) ty2 = ty1 `unifyTypes` ty2-  unifyTypes' ty1 (KindedType ty2 _) = ty1 `unifyTypes` ty2-  unifyTypes' r1@RCons{} r2 = unifyRows r1 r2-  unifyTypes' r1 r2@RCons{} = unifyRows r1 r2-  unifyTypes' r1@REmpty r2 = unifyRows r1 r2-  unifyTypes' r1 r2@REmpty = unifyRows r1 r2-  unifyTypes' t@(ConstrainedType _ _) _ = throwError . strMsg $ "Attempted to unify a constrained type " ++ prettyPrintType t ++ " with another type."-  unifyTypes' t3 t4@(ConstrainedType _ _) = unifyTypes' t4 t3-  unifyTypes' t3 t4 = throwError . strMsg $ "Cannot unify " ++ prettyPrintType t3 ++ " with " ++ prettyPrintType t4 ++ "."---- |--- Unify two rows, updating the current substitution------ Common labels are first identified, and unified. Remaining labels and types are unified with a--- trailing row unification variable, if appropriate, otherwise leftover labels result in a unification--- error.----unifyRows :: Type -> Type -> UnifyT Type Check ()-unifyRows r1 r2 =-  let-    (s1, r1') = rowToList r1-    (s2, r2') = rowToList r2-    int = [ (t1, t2) | (name, t1) <- s1, (name', t2) <- s2, name == name' ]-    sd1 = [ (name, t1) | (name, t1) <- s1, name `notElem` map fst s2 ]-    sd2 = [ (name, t2) | (name, t2) <- s2, name `notElem` map fst s1 ]-  in do-    forM_ int (uncurry (=?=))-    unifyRows' sd1 r1' sd2 r2'-  where-  unifyRows' :: [(String, Type)] -> Type -> [(String, Type)] -> Type -> UnifyT Type Check ()-  unifyRows' [] (TUnknown u) sd r = u =:= rowFromList (sd, r)-  unifyRows' sd r [] (TUnknown u) = u =:= rowFromList (sd, r)-  unifyRows' sd1 (TUnknown u1) sd2 (TUnknown u2) = do-    forM_ sd1 $ \(_, t) -> occursCheck u2 t-    forM_ sd2 $ \(_, t) -> occursCheck u1 t-    rest <- fresh-    u1 =:= rowFromList (sd2, rest)-    u2 =:= rowFromList (sd1, rest)-  unifyRows' [] REmpty [] REmpty = return ()-  unifyRows' [] (TypeVar v1) [] (TypeVar v2) | v1 == v2 = return ()-  unifyRows' [] (Skolem _ s1 _) [] (Skolem _ s2 _) | s1 == s2 = return ()-  unifyRows' sd3 r3 sd4 r4 = throwError . strMsg $ "Cannot unify (" ++ prettyPrintRow (rowFromList (sd3, r3)) ++ ") with (" ++ prettyPrintRow (rowFromList (sd4, r4)) ++ ")"---- | -- Infer the types of multiple mutually-recursive values, and return elaborated values including -- type class dictionaries and type annotations. --@@ -232,15 +129,17 @@  checkTypedBindingGroupElement :: ModuleName -> (Ident, (Expr, Type, Bool)) -> TypeData ->  UnifyT Type Check (Ident, (Expr, Type)) checkTypedBindingGroupElement moduleName (ident, (val', ty, checkType)) dict = do+  -- Replace type wildcards+  ty' <- replaceTypeWildcards ty   -- Kind check   kind <- liftCheck $ kindOf moduleName ty   guardWith (strMsg $ "Expected type of kind *, was " ++ prettyPrintKind kind) $ kind == Star   -- Check the type with the new names in scope-  ty' <- introduceSkolemScope <=< replaceAllTypeSynonyms $ ty+  ty'' <- introduceSkolemScope <=< replaceAllTypeSynonyms <=< replaceTypeWildcards $ ty'   val'' <- if checkType-           then bindNames dict $ TypedValue True <$> check val' ty' <*> pure ty'-           else return (TypedValue False val' ty')-  return (ident, (val'', ty'))+           then bindNames dict $ TypedValue True <$> check val' ty'' <*> pure ty''+           else return (TypedValue False val' ty'')+  return (ident, (val'', ty''))  typeForBindingGroupElement :: (Ident, Expr) -> TypeData -> UntypedData -> UnifyT Type Check (Ident, (Expr, Type)) typeForBindingGroupElement (ident, val) dict untypedDict = do@@ -252,7 +151,7 @@ -- | -- Check if a value contains a type annotation ---isTyped :: (Ident, Expr) -> (Either (Ident, Expr) (Ident, (Expr, Type, Bool)))+isTyped :: (Ident, Expr) -> Either (Ident, Expr) (Ident, (Expr, Type, Bool)) isTyped (name, TypedValue checkType value ty) = Right (name, (value, ty, checkType)) isTyped (name, value) = Left (name, value) @@ -281,291 +180,12 @@   go other = return other  -- |--- A simplified representation of expressions which are used to represent type--- class dictionaries at runtime, which can be compared for equality----data DictionaryValue-  -- |-  -- A dictionary which is brought into scope by a local constraint-  ---  = LocalDictionaryValue (Qualified Ident)-  -- |-  -- A dictionary which is brought into scope by an instance declaration-  ---  | GlobalDictionaryValue (Qualified Ident)-  -- |-  -- A dictionary which depends on other dictionaries-  ---  | DependentDictionaryValue (Qualified Ident) [DictionaryValue]-  -- |-  -- A subclass dictionary-  ---  | SubclassDictionaryValue DictionaryValue (Qualified ProperName) Integer-  deriving (Show, Ord, Eq)---- |--- Check that the current set of type class dictionaries entail the specified type class goal, and, if so,--- return a type class dictionary reference.----entails :: Environment -> ModuleName -> [TypeClassDictionaryInScope] -> (Qualified ProperName, [Type]) -> Bool -> Check Expr-entails env moduleName context = solve (sortedNubBy canonicalizeDictionary (filter filterModule context))-  where-    sortedNubBy :: (Ord k) => (v -> k) -> [v] -> [v]-    sortedNubBy f vs = M.elems (M.fromList (map (f &&& id) vs))--    -- Filter out type dictionaries which are in scope in the current module-    filterModule :: TypeClassDictionaryInScope -> Bool-    filterModule (TypeClassDictionaryInScope { tcdName = Qualified (Just mn) _ }) | mn == moduleName = True-    filterModule (TypeClassDictionaryInScope { tcdName = Qualified Nothing _ }) = True-    filterModule _ = False--    solve context' (className, tys) trySuperclasses =-      checkOverlaps $ go trySuperclasses className tys-      where-      go trySuperclasses' className' tys' =-        -- Look for regular type instances-        [ mkDictionary (canonicalizeDictionary tcd) args-        | tcd <- context'-        -- Make sure the type class name matches the one we are trying to satisfy-        , className' == tcdClassName tcd-        -- Make sure the type unifies with the type in the type instance definition-        , subst <- maybeToList . (>>= verifySubstitution) . fmap concat $ zipWithM (typeHeadsAreEqual moduleName env) tys' (tcdInstanceTypes tcd)-        -- Solve any necessary subgoals-        , args <- solveSubgoals subst (tcdDependencies tcd) ] ++-      -        -- Look for implementations via superclasses-        [ SubclassDictionaryValue suDict superclass index-        | trySuperclasses'-        , (subclassName, (args, _, implies)) <- M.toList (typeClasses env)-        -- Try each superclass-        , (index, (superclass, suTyArgs)) <- zip [0..] implies-        -- Make sure the type class name matches the superclass name-        , className' == superclass-        -- Make sure the types unify with the types in the superclass implication-        , subst <- maybeToList . (>>= verifySubstitution) . fmap concat $ zipWithM (typeHeadsAreEqual moduleName env) tys' suTyArgs-        -- Finally, satisfy the subclass constraint-        , args' <- maybeToList $ mapM (flip lookup subst) (map fst args)-        , suDict <- go True subclassName args' ]-      -      -- Create dictionaries for subgoals which still need to be solved by calling go recursively-      -- E.g. the goal (Show a, Show b) => Show (Either a b) can be satisfied if the current type-      -- unifies with Either a b, and we can satisfy the subgoals Show a and Show b recursively.-      solveSubgoals :: [(String, Type)] -> Maybe [(Qualified ProperName, [Type])] -> [Maybe [DictionaryValue]]-      solveSubgoals _ Nothing = return Nothing-      solveSubgoals subst (Just subgoals) = do-        dict <- mapM (uncurry (go True) . second (map (replaceAllTypeVars subst))) subgoals-        return $ Just dict-      -- Make a dictionary from subgoal dictionaries by applying the correct function-      mkDictionary :: Qualified Ident -> Maybe [DictionaryValue] -> DictionaryValue-      mkDictionary fnName Nothing = LocalDictionaryValue fnName-      mkDictionary fnName (Just []) = GlobalDictionaryValue fnName-      mkDictionary fnName (Just dicts) = DependentDictionaryValue fnName dicts-      -- Turn a DictionaryValue into a Expr-      dictionaryValueToValue :: DictionaryValue -> Expr-      dictionaryValueToValue (LocalDictionaryValue fnName) = Var fnName-      dictionaryValueToValue (GlobalDictionaryValue fnName) = Var fnName-      dictionaryValueToValue (DependentDictionaryValue fnName dicts) = foldl App (Var fnName) (map dictionaryValueToValue dicts)-      dictionaryValueToValue (SubclassDictionaryValue dict superclassName index) =-        App (Accessor (C.__superclass_ ++ show superclassName ++ "_" ++ show index)-                      (dictionaryValueToValue dict))-            valUndefined-      -- Ensure that a substitution is valid-      verifySubstitution :: [(String, Type)] -> Maybe [(String, Type)]-      verifySubstitution subst = do-        let grps = groupBy ((==) `on` fst) subst-        guard (all (pairwise (unifiesWith env) . map snd) grps)-        return $ map head grps-      -- |-      -- Check for overlapping instances-      ---      checkOverlaps :: [DictionaryValue] -> Check Expr    -      checkOverlaps dicts = -        case [ (d1, d2) | d1 <- dicts, d2 <- dicts, d1 `overlapping` d2 ] of-          (d1, d2) : _ -> throwError . strMsg $ unlines-            [ "Overlapping instances found for " ++ show className ++ " " ++ unwords (map prettyPrintType tys) ++ "."-            , "For example:"-            , prettyPrintDictionaryValue d1-            , "and:"-            , prettyPrintDictionaryValue d2-            ]-          _ -> case chooseSimplestDictionaries dicts of-                 [] -> throwError . strMsg $ -                         "No instance found for " ++ show className ++ " " ++ unwords (map prettyPrintTypeAtom tys)-                 d : _ -> return $ dictionaryValueToValue d-      -- Choose the simplest DictionaryValues from a list of candidates-      -- The reason for this function is as follows:-      -- When considering overlapping instances, we don't want to consider the same dictionary-      -- to be an overlap of itself when obtained as a superclass of another class.-      -- Observing that we probably don't want to select a superclass instance when an instance-      -- is available directly, and that there is no way for a superclass instance to actually-      -- introduce an overlap that wouldn't have been there already, we simply remove dictionaries-      -- obtained as superclass instances if there are simpler instances available.-      chooseSimplestDictionaries :: [DictionaryValue] -> [DictionaryValue]-      chooseSimplestDictionaries ds = case filter isSimpleDictionaryValue ds of-                                        [] -> ds-                                        simple -> simple-      isSimpleDictionaryValue SubclassDictionaryValue{} = False-      isSimpleDictionaryValue (DependentDictionaryValue _ ds) = all isSimpleDictionaryValue ds-      isSimpleDictionaryValue _ = True-      -- |-      -- Check if two dictionaries are overlapping-      -- -      -- Dictionaries which are subclass dictionaries cannot overlap, since otherwise the overlap would have-      -- been caught when constructing superclass dictionaries.-      ---      overlapping :: DictionaryValue -> DictionaryValue -> Bool-      overlapping (LocalDictionaryValue nm1)         (LocalDictionaryValue nm2)  | nm1 == nm2 = False-      overlapping (GlobalDictionaryValue nm1)        (GlobalDictionaryValue nm2) | nm1 == nm2 = False-      overlapping (DependentDictionaryValue nm1 ds1) (DependentDictionaryValue nm2 ds2) -        | nm1 == nm2 = any id $ zipWith overlapping ds1 ds2-      overlapping (SubclassDictionaryValue _ _ _) _ = False-      overlapping _ (SubclassDictionaryValue _ _ _) = False-      overlapping _ _ = True-      -- |-      -- Render a DictionaryValue fit for human consumption in error messages-      ---      prettyPrintDictionaryValue :: DictionaryValue -> String-      prettyPrintDictionaryValue = unlines . indented 0-        where-        indented n (LocalDictionaryValue _)           = [spaces n ++ "Dictionary in scope"]-        indented n (GlobalDictionaryValue nm)         = [spaces n ++ show nm]-        indented n (DependentDictionaryValue nm args) = (spaces n ++ show nm ++ " via") : concatMap (indented (n + 2)) args-        indented n (SubclassDictionaryValue sup nm _) = (spaces n ++ show nm ++ " via superclass") : indented (n + 2) sup-        -        spaces n = replicate n ' ' ++ "- "--    valUndefined :: Expr-    valUndefined = Var (Qualified (Just (ModuleName [ProperName C.prim])) (Ident C.undefined))---- |--- Check all values in a list pairwise match a predicate----pairwise :: (a -> a -> Bool) -> [a] -> Bool-pairwise _ [] = True-pairwise _ [_] = True-pairwise p (x : xs) = all (p x) xs && pairwise p xs---- |--- Check that two types unify----unifiesWith :: Environment -> Type -> Type -> Bool-unifiesWith _ (TUnknown u1) (TUnknown u2) | u1 == u2 = True-unifiesWith _ (Skolem _ s1 _) (Skolem _ s2 _) | s1 == s2 = True-unifiesWith _ (TypeVar v1) (TypeVar v2) | v1 == v2 = True-unifiesWith _ (TypeConstructor c1) (TypeConstructor c2) | c1 == c2 = True-unifiesWith e (TypeApp h1 t1) (TypeApp h2 t2) = unifiesWith e h1 h2 && unifiesWith e t1 t2-unifiesWith e (SaturatedTypeSynonym name args) t2 =-  case expandTypeSynonym' e name args of-    Left  _  -> False-    Right t1 -> unifiesWith e t1 t2-unifiesWith e t1 t2@(SaturatedTypeSynonym _ _) = unifiesWith e t2 t1-unifiesWith _ _ _ = False---- |--- Check whether the type heads of two types are equal (for the purposes of type class dictionary lookup),--- and return a substitution from type variables to types which makes the type heads unify.----typeHeadsAreEqual :: ModuleName -> Environment -> Type -> Type -> Maybe [(String, Type)]-typeHeadsAreEqual _ _ (Skolem _ s1 _) (Skolem _ s2 _) | s1 == s2 = Just []-typeHeadsAreEqual _ _ t (TypeVar v) = Just [(v, t)]-typeHeadsAreEqual _ _ (TypeConstructor c1) (TypeConstructor c2) | c1 == c2 = Just []-typeHeadsAreEqual m e (TypeApp h1 t1) (TypeApp h2 t2) = (++) <$> typeHeadsAreEqual m e h1 h2 <*> typeHeadsAreEqual m e t1 t2-typeHeadsAreEqual m e (SaturatedTypeSynonym name args) t2 = case expandTypeSynonym' e name args of-  Left  _  -> Nothing-  Right t1 -> typeHeadsAreEqual m e t1 t2-typeHeadsAreEqual _ _ _ _ = Nothing---- |--- Ensure skolem variables do not escape their scope----skolemEscapeCheck :: Expr -> Check ()-skolemEscapeCheck (TypedValue False _ _) = return ()-skolemEscapeCheck root@TypedValue{} =-  -- Every skolem variable is created when a ForAll type is skolemized.-  -- This determines the scope of that skolem variable, which is copied from the SkolemScope-  -- field of the ForAll constructor.-  -- We traverse the tree top-down, and collect any SkolemScopes introduced by ForAlls.-  -- If a Skolem is encountered whose SkolemScope is not in the current list, we have found-  -- an escaped skolem variable.-  let (_, f, _, _, _) = everythingWithContextOnValues [] [] (++) def go def def def-  in case f root of-       [] -> return ()-       ((binding, val) : _) -> throwError $ mkErrorStack ("Rigid/skolem type variable " ++ maybe "" (("bound by " ++) . prettyPrintValue) binding ++ " has escaped.") (Just (ExprError val))-  where-  def s _ = (s, [])--  go :: [(SkolemScope, Expr)] -> Expr -> ([(SkolemScope, Expr)], [(Maybe Expr, Expr)])-  go scos val@(TypedValue _ _ (ForAll _ _ (Just sco))) = ((sco, val) : scos, [])-  go scos val@(TypedValue _ _ ty) = case collectSkolems ty \\ map fst scos of-                                      (sco : _) -> (scos, [(findBindingScope sco, val)])-                                      _ -> (scos, [])-    where-    collectSkolems :: Type -> [SkolemScope]-    collectSkolems = nub . everythingOnTypes (++) collect-      where-      collect (Skolem _ _ scope) = [scope]-      collect _ = []-  go scos _ = (scos, [])-  findBindingScope :: SkolemScope -> Maybe Expr-  findBindingScope sco =-    let (_, f, _, _, _) = everythingOnValues mappend (const mempty) go' (const mempty) (const mempty) (const mempty)-    in getFirst $ f root-    where-    go' val@(TypedValue _ _ (ForAll _ _ (Just sco'))) | sco == sco' = First (Just val)-    go' _ = mempty-skolemEscapeCheck val = throwError $ mkErrorStack "Untyped value passed to skolemEscapeCheck" (Just (ExprError val))---- |--- Ensure rows do not contain duplicate labels----checkDuplicateLabels :: Expr -> Check ()-checkDuplicateLabels = -  let (_, f, _) = everywhereOnValuesM def go def -  in void . f-  where -  def :: a -> Check a-  def = return-   -  go :: Expr -> Check Expr-  go e@(TypedValue _ val ty) = do-    checkDups ty-    return e-    -    where-    checkDups :: Type -> Check ()-    checkDups (TypeApp t1 t2) = checkDups t1 >> checkDups t2-    checkDups (SaturatedTypeSynonym _ ts) = mapM_ checkDups ts-    checkDups (ForAll _ t _) = checkDups t-    checkDups (ConstrainedType args t) = do-      mapM_ (checkDups) $ concatMap snd args-      checkDups t -    checkDups r@(RCons _ _ _) = -      let (ls, _) = rowToList r in -      case firstDup . sort . map fst $ ls of-        Just l -> throwError $ mkErrorStack ("Duplicate label " ++ show l ++ " in row") $ Just (ExprError val)-        Nothing -> return ()-    checkDups _ = return ()-  -    firstDup :: (Eq a) => [a] -> Maybe a-    firstDup (x : xs@(x' : _)) -      | x == x' = Just x-      | otherwise = firstDup xs-    firstDup _ = Nothing    -        -  go other = return other-  --- |--- Replace outermost unsolved unification variables with named type variables+-- Check the kind of a type, failing if it is not of kind *. ---varIfUnknown :: Type -> Type-varIfUnknown ty =-  let unks = nub $ unknowns ty-      toName = (:) 't' . show-      ty' = everywhereOnTypes typeToVar ty-      typeToVar :: Type -> Type-      typeToVar (TUnknown u) = TypeVar (toName u)-      typeToVar t = t-  in mkForAll (sort . map toName $ unks) ty'+checkTypeKind :: ModuleName -> Type -> UnifyT t Check ()+checkTypeKind moduleName ty = do+  kind <- liftCheck $ kindOf moduleName ty+  guardWith (strMsg $ "Expected type of kind *, was " ++ prettyPrintKind kind) $ kind == Star  -- | -- Remove any ForAlls and ConstrainedType constructors in a type by introducing new unknowns@@ -585,67 +205,6 @@ instantiatePolyTypeWithUnknowns val ty = return (val, ty)  -- |--- Replace a single type variable with a new unification variable----replaceVarWithUnknown :: String -> Type -> UnifyT Type Check Type-replaceVarWithUnknown ident ty = do-  tu <- fresh-  return $ replaceTypeVars ident tu ty---- |--- Replace fully applied type synonyms with the @SaturatedTypeSynonym@ data constructor, which helps generate--- better error messages during unification.----replaceAllTypeSynonyms' :: Environment -> Type -> Either String Type-replaceAllTypeSynonyms' env d =-  let-    syns = map (\(name, (args, _)) -> (name, length args)) . M.toList $ typeSynonyms env-  in-    saturateAllTypeSynonyms syns d--replaceAllTypeSynonyms :: (Error e, Functor m, Monad m, MonadState CheckState m, MonadError e m) => Type -> m Type-replaceAllTypeSynonyms d = do-  env <- getEnv-  either (throwError . strMsg) return $ replaceAllTypeSynonyms' env d---- |--- \"Desaturate\" @SaturatedTypeSynonym@s----desaturateAllTypeSynonyms :: Type -> Type-desaturateAllTypeSynonyms = everywhereOnTypes replaceSaturatedTypeSynonym-  where-  replaceSaturatedTypeSynonym (SaturatedTypeSynonym name args) = foldl TypeApp (TypeConstructor name) args-  replaceSaturatedTypeSynonym t = t---- |--- Replace a type synonym and its arguments with the aliased type----expandTypeSynonym' :: Environment -> Qualified ProperName -> [Type] -> Either String Type-expandTypeSynonym' env name args =-  case M.lookup name (typeSynonyms env) of-    Just (synArgs, body) -> do-      let repl = replaceAllTypeVars (zip (map fst synArgs) args) body-      replaceAllTypeSynonyms' env repl-    Nothing -> error "Type synonym was not defined"--expandTypeSynonym :: (Error e, Functor m, Monad m, MonadState CheckState m, MonadError e m) => Qualified ProperName -> [Type] -> m Type-expandTypeSynonym name args = do-  env <- getEnv-  either (throwError . strMsg) return $ expandTypeSynonym' env name args--expandAllTypeSynonyms :: (Error e, Functor m, Applicative m, Monad m, MonadState CheckState m, MonadError e m) => Type -> m Type-expandAllTypeSynonyms = everywhereOnTypesTopDownM go-  where-  go (SaturatedTypeSynonym name args) = expandTypeSynonym name args-  go other = return other---- |--- Ensure a set of property names and value does not contain duplicate labels----ensureNoDuplicateProperties :: (Error e, MonadError e m) => [(String, Expr)] -> m ()-ensureNoDuplicateProperties ps = guardWith (strMsg "Duplicate property names") $ length (nub . map fst $ ps) == length ps---- | -- Infer a type for a value, rethrowing any error to provide a more useful error message -- infer :: Expr -> UnifyT Type Check Expr@@ -702,7 +261,7 @@ infer' (Var var) = do   Just moduleName <- checkCurrentModule <$> get   checkVisibility moduleName var-  ty <- introduceSkolemScope <=< replaceAllTypeSynonyms <=< lookupVariable moduleName $ var+  ty <- introduceSkolemScope <=< replaceAllTypeSynonyms <=< replaceTypeWildcards <=< lookupVariable moduleName $ var   case ty of     ConstrainedType constraints ty' -> do       dicts <- getTypeClassDictionaries@@ -733,9 +292,8 @@   return $ TypeClassDictionary False (className, tys) dicts infer' (TypedValue checkType val ty) = do   Just moduleName <- checkCurrentModule <$> get-  kind <- liftCheck $ kindOf moduleName ty-  guardWith (strMsg $ "Expected type of kind *, was " ++ prettyPrintKind kind) $ kind == Star-  ty' <- introduceSkolemScope <=< replaceAllTypeSynonyms $ ty+  checkTypeKind moduleName ty+  ty' <- introduceSkolemScope <=< replaceAllTypeSynonyms <=< replaceTypeWildcards $ ty   val' <- if checkType then check val ty' else return val   return $ TypedValue True val' ty' infer' (PositionedValue pos val) = rethrowWithPosition pos $ infer' val@@ -743,21 +301,20 @@  inferLetBinding :: [Declaration] -> [Declaration] -> Expr -> (Expr -> UnifyT Type Check Expr) -> UnifyT Type Check ([Declaration], Expr) inferLetBinding seen [] ret j = (,) seen <$> makeBindingGroupVisible (j ret)-inferLetBinding seen (ValueDeclaration ident nameKind [] Nothing tv@(TypedValue checkType val ty) : rest) ret j = do+inferLetBinding seen (ValueDeclaration ident nameKind [] (Right (tv@(TypedValue checkType val ty))) : rest) ret j = do   Just moduleName <- checkCurrentModule <$> get-  kind <- liftCheck $ kindOf moduleName ty-  guardWith (strMsg $ "Expected type of kind *, was " ++ prettyPrintKind kind) $ kind == Star+  checkTypeKind moduleName ty   let dict = M.singleton (moduleName, ident) (ty, nameKind, Undefined)-  ty' <- introduceSkolemScope <=< replaceAllTypeSynonyms $ ty+  ty' <- introduceSkolemScope <=< replaceAllTypeSynonyms <=< replaceTypeWildcards $ ty   TypedValue _ val' ty'' <- if checkType then bindNames dict (check val ty') else return tv-  bindNames (M.singleton (moduleName, ident) (ty'', nameKind, Defined)) $ inferLetBinding (seen ++ [ValueDeclaration ident nameKind [] Nothing (TypedValue checkType val' ty'')]) rest ret j-inferLetBinding seen (ValueDeclaration ident nameKind [] Nothing val : rest) ret j = do+  bindNames (M.singleton (moduleName, ident) (ty'', nameKind, Defined)) $ inferLetBinding (seen ++ [ValueDeclaration ident nameKind [] (Right (TypedValue checkType val' ty''))]) rest ret j+inferLetBinding seen (ValueDeclaration ident nameKind [] (Right val) : rest) ret j = do   valTy <- fresh   Just moduleName <- checkCurrentModule <$> get   let dict = M.singleton (moduleName, ident) (valTy, nameKind, Undefined)   TypedValue _ val' valTy' <- bindNames dict $ infer val   valTy =?= valTy'-  bindNames (M.singleton (moduleName, ident) (valTy', nameKind, Defined)) $ inferLetBinding (seen ++ [ValueDeclaration ident nameKind [] Nothing val']) rest ret j+  bindNames (M.singleton (moduleName, ident) (valTy', nameKind, Defined)) $ inferLetBinding (seen ++ [ValueDeclaration ident nameKind [] (Right val')]) rest ret j inferLetBinding seen (BindingGroupDeclaration ds : rest) ret j = do   Just moduleName <- checkCurrentModule <$> get   (untyped, typed, dict, untypedDict) <- typeDictionaryForBindingGroup moduleName (map (\(i, _, v) -> (i, v)) ds)@@ -766,7 +323,7 @@   let ds' = [(ident, LocalVariable, val') | (ident, (val', _)) <- ds1' ++ ds2']   makeBindingGroupVisible $ bindNames dict $ inferLetBinding (seen ++ [BindingGroupDeclaration ds']) rest ret j inferLetBinding seen (PositionedDeclaration pos d : ds) ret j = rethrowWithPosition pos $ do-  ((d' : ds'), val') <- inferLetBinding seen (d : ds) ret j+  (d' : ds', val') <- inferLetBinding seen (d : ds) ret j   return (PositionedDeclaration pos d' : ds', val') inferLetBinding _ _ _ _ = error "Invalid argument to inferLetBinding" @@ -845,60 +402,27 @@ -- checkBinders :: [Type] -> Type -> [CaseAlternative] -> UnifyT Type Check [CaseAlternative] checkBinders _ _ [] = return []-checkBinders nvals ret (CaseAlternative binders grd val : bs) = do+checkBinders nvals ret (CaseAlternative binders result : bs) = do   guardWith (strMsg "Overlapping binders in case statement") $     let ns = concatMap binderNames binders in length (nub ns) == length ns   Just moduleName <- checkCurrentModule <$> get   m1 <- M.unions <$> zipWithM inferBinder nvals binders-  r <- bindLocalVariables moduleName [ (name, ty, Defined) | (name, ty) <- M.toList m1 ] $ do-    val' <- TypedValue True <$> check val ret <*> pure ret-    case grd of-      Nothing -> return $ CaseAlternative binders Nothing val'-      Just g -> do-        g' <- check g tyBoolean-        return $ CaseAlternative binders (Just g') val'+  r <- bindLocalVariables moduleName [ (name, ty, Defined) | (name, ty) <- M.toList m1 ] $+    CaseAlternative binders <$>+      case result of+        Left gs -> do+          gs' <- forM gs $ \(grd, val) -> do+            grd' <- check grd tyBoolean+            val' <- TypedValue True <$> check val ret <*> pure ret+            return (grd', val')+          return $ Left gs'+        Right val -> do+          val' <- TypedValue True <$> check val ret <*> pure ret+          return $ Right val'   rs <- checkBinders nvals ret bs   return $ r : rs  -- |--- Generate a new skolem constant----newSkolemConstant :: UnifyT Type Check Int-newSkolemConstant = fresh'---- |--- Generate a new skolem scope----newSkolemScope :: UnifyT Type Check SkolemScope-newSkolemScope = SkolemScope <$> fresh'---- |--- Skolemize a type variable by replacing its instances with fresh skolem constants----skolemize :: String -> Int -> SkolemScope -> Type -> Type-skolemize ident sko scope = replaceTypeVars ident (Skolem ident sko scope)---- |--- This function has one purpose - to skolemize type variables appearing in a--- SuperClassDictionary placeholder. These type variables are somewhat unique since they are the--- only example of scoped type variables.----skolemizeTypesInValue :: String -> Int -> SkolemScope -> Expr -> Expr-skolemizeTypesInValue ident sko scope = let (_, f, _) = everywhereOnValues id go id in f-  where-  go (SuperClassDictionary c ts) = SuperClassDictionary c (map (skolemize ident sko scope) ts)-  go other = other---- |--- Introduce skolem scope at every occurence of a ForAll----introduceSkolemScope :: Type -> UnifyT Type Check Type-introduceSkolemScope = everywhereOnTypesM go-  where-  go (ForAll ident ty Nothing) = ForAll ident ty <$> (Just <$> newSkolemScope)-  go other = return other---- | -- Check the type of a value, rethrowing errors to provide a better error message -- check :: Expr -> Type -> UnifyT Type Check Expr@@ -961,7 +485,7 @@   Just moduleName <- checkCurrentModule <$> get   checkVisibility moduleName var   repl <- introduceSkolemScope <=< replaceAllTypeSynonyms <=< lookupVariable moduleName $ var-  ty' <- introduceSkolemScope <=< replaceAllTypeSynonyms $ ty+  ty' <- introduceSkolemScope <=< replaceAllTypeSynonyms <=< replaceTypeWildcards $ ty   v' <- subsumes (Just v) repl ty'   case v' of     Nothing -> throwError . strMsg $ "Unable to check type subsumption"@@ -981,10 +505,9 @@   return $ TypeClassDictionary False (className, tys) dicts check' (TypedValue checkType val ty1) ty2 = do   Just moduleName <- checkCurrentModule <$> get-  kind <- liftCheck $ kindOf moduleName ty1-  guardWith (strMsg $ "Expected type of kind *, was " ++ prettyPrintKind kind) $ kind == Star-  ty1' <- introduceSkolemScope <=< replaceAllTypeSynonyms $ ty1-  ty2' <- introduceSkolemScope <=< replaceAllTypeSynonyms $ ty2+  checkTypeKind moduleName ty1+  ty1' <- introduceSkolemScope <=< replaceAllTypeSynonyms <=< replaceTypeWildcards $ ty1+  ty2' <- introduceSkolemScope <=< replaceAllTypeSynonyms <=< replaceTypeWildcards $ ty2   val' <- subsumes (Just val) ty1' ty2'   case val' of     Nothing -> throwError . strMsg $ "Unable to check type subsumption"@@ -1031,10 +554,10 @@       _ <- subsumes Nothing repl ty       return $ TypedValue True (Constructor c) ty check' (Let ds val) ty = do-  (ds', val') <- inferLetBinding [] ds val (flip check ty)+  (ds', val') <- inferLetBinding [] ds val (`check` ty)   return $ TypedValue True (Let ds' val') ty check' val ty | containsTypeSynonyms ty = do-  ty' <- introduceSkolemScope <=< expandAllTypeSynonyms $ ty+  ty' <- introduceSkolemScope <=< expandAllTypeSynonyms <=< replaceTypeWildcards $ ty   check val ty' check' val kt@(KindedType ty kind) = do   guardWith (strMsg $ "Expected type of kind *, was " ++ prettyPrintKind kind) $ kind == Star@@ -1059,7 +582,7 @@   go [] [] REmpty = return []   go [] [] u@(TUnknown _) = do u =?= REmpty                                return []-  go [] [] (Skolem _ _ _) | lax = return []+  go [] [] Skolem{} | lax = return []   go [] ((p, _): _) _ | lax = return []                       | otherwise = throwError $ mkErrorStack ("Object does not have property " ++ p) (Just (ExprError (ObjectLiteral ps)))   go ((p,_):_) [] REmpty = throwError $ mkErrorStack ("Property " ++ p ++ " is not present in closed object type " ++ prettyPrintRow row) (Just (ExprError (ObjectLiteral ps)))@@ -1122,85 +645,18 @@ checkFunctionApplication' fn (SaturatedTypeSynonym name tyArgs) arg ret = do   ty <- introduceSkolemScope <=< expandTypeSynonym name $ tyArgs   checkFunctionApplication fn ty arg ret-checkFunctionApplication' fn (KindedType ty _) arg ret = do+checkFunctionApplication' fn (KindedType ty _) arg ret =   checkFunctionApplication fn ty arg ret checkFunctionApplication' fn (ConstrainedType constraints fnTy) arg ret = do   dicts <- getTypeClassDictionaries   checkFunctionApplication' (foldl App fn (map (flip (TypeClassDictionary True) dicts) constraints)) fnTy arg ret-checkFunctionApplication' fn fnTy dict@(TypeClassDictionary _ _ _) _ =+checkFunctionApplication' fn fnTy dict@TypeClassDictionary{} _ =   return (fnTy, App fn dict) checkFunctionApplication' _ fnTy arg _ = throwError . strMsg $ "Cannot apply a function of type "   ++ prettyPrintType fnTy   ++ " to argument " ++ prettyPrintValue arg  -- |--- Check whether one type subsumes another, rethrowing errors to provide a better error message----subsumes :: Maybe Expr -> Type -> Type -> UnifyT Type Check (Maybe Expr)-subsumes val ty1 ty2 = rethrow (mkErrorStack errorMessage (ExprError <$> val) <>) $ subsumes' val ty1 ty2-  where-  errorMessage = "Error checking that type "-    ++ prettyPrintType ty1-    ++ " subsumes type "-    ++ prettyPrintType ty2---- |--- Check whether one type subsumes another----subsumes' :: Maybe Expr -> Type -> Type -> UnifyT Type Check (Maybe Expr)-subsumes' val (ForAll ident ty1 _) ty2 = do-  replaced <- replaceVarWithUnknown ident ty1-  subsumes val replaced ty2-subsumes' val ty1 (ForAll ident ty2 sco) =-  case sco of-    Just sco' -> do-      sko <- newSkolemConstant-      let sk = skolemize ident sko sco' ty2-      subsumes val ty1 sk-    Nothing -> throwError . strMsg $ "Skolem variable scope is unspecified"-subsumes' val (TypeApp (TypeApp f1 arg1) ret1) (TypeApp (TypeApp f2 arg2) ret2) | f1 == tyFunction && f2 == tyFunction = do-  _ <- subsumes Nothing arg2 arg1-  _ <- subsumes Nothing ret1 ret2-  return val-subsumes' val (SaturatedTypeSynonym name tyArgs) ty2 = do-  ty1 <- introduceSkolemScope <=< expandTypeSynonym name $ tyArgs-  subsumes val ty1 ty2-subsumes' val ty1 (SaturatedTypeSynonym name tyArgs) = do-  ty2 <- introduceSkolemScope <=< expandTypeSynonym name $ tyArgs-  subsumes val ty1 ty2-subsumes' val (KindedType ty1 _) ty2 = do-  subsumes val ty1 ty2-subsumes' val ty1 (KindedType ty2 _) = do-  subsumes val ty1 ty2-subsumes' (Just val) (ConstrainedType constraints ty1) ty2 = do-  dicts <- getTypeClassDictionaries-  subsumes' (Just $ foldl App val (map (flip (TypeClassDictionary True) dicts) constraints)) ty1 ty2-subsumes' val (TypeApp f1 r1) (TypeApp f2 r2) | f1 == tyObject && f2 == tyObject = do-  let-    (ts1, r1') = rowToList r1-    (ts2, r2') = rowToList r2-    ts1' = sortBy (comparing fst) ts1-    ts2' = sortBy (comparing fst) ts2-  go ts1' ts2' r1' r2'-  return val-  where-  go [] ts2 r1' r2' = r1' =?= rowFromList (ts2, r2')-  go ts1 [] r1' r2' = r2' =?= rowFromList (ts1, r1')-  go ((p1, ty1) : ts1) ((p2, ty2) : ts2) r1' r2'-    | p1 == p2 = do _ <- subsumes Nothing ty1 ty2-                    go ts1 ts2 r1' r2'-    | p1 < p2 = do rest <- fresh-                   r2' =?= RCons p1 ty1 rest-                   go ts1 ((p2, ty2) : ts2) r1' rest-    | otherwise = do rest <- fresh-                     r1' =?= RCons p2 ty2 rest-                     go ((p1, ty1) : ts1) ts2 rest r2'-subsumes' val ty1 ty2@(TypeApp obj _) | obj == tyObject = subsumes val ty2 ty1-subsumes' val ty1 ty2 = do-  ty1 =?= ty2-  return val---- | -- Compute the meet of two types, i.e. the most general type which both types subsume. -- TODO: handle constrained types --@@ -1215,9 +671,8 @@   t1 =?= t2   return (e1, e2, t1) ------+-- |+-- Ensure a set of property names and value does not contain duplicate labels+--+ensureNoDuplicateProperties :: (Error e, MonadError e m) => [(String, Expr)] -> m ()+ensureNoDuplicateProperties ps = guardWith (strMsg "Duplicate property names") $ length (nub . map fst $ ps) == length ps
+ src/Language/PureScript/TypeChecker/Unify.hs view
@@ -0,0 +1,184 @@+-----------------------------------------------------------------------------+--+-- Module      :  Language.PureScript.TypeChecker.Unify+-- Copyright   :  (c) Phil Freeman 2013+-- License     :  MIT+--+-- Maintainer  :  Phil Freeman <paf31@cantab.net>+-- Stability   :  experimental+-- Portability :+--+-- |+-- Functions and instances relating to unification+--+-----------------------------------------------------------------------------++{-# OPTIONS_GHC -fno-warn-orphans #-}+{-# LANGUAGE FlexibleInstances, FlexibleContexts, MultiParamTypeClasses #-}++module Language.PureScript.TypeChecker.Unify (+    unifyTypes,+    unifyRows,+    unifiesWith,+    replaceVarWithUnknown,+    replaceTypeWildcards,+    varIfUnknown+) where++import Data.List (nub, sort)+import Data.Maybe (fromMaybe)+import Data.Monoid+import qualified Data.HashMap.Strict as H++import Control.Monad.Error+import Control.Monad.Unify++import Language.PureScript.Environment+import Language.PureScript.Errors+import Language.PureScript.Pretty+import Language.PureScript.TypeChecker.Monad+import Language.PureScript.TypeChecker.Skolems+import Language.PureScript.TypeChecker.Synonyms+import Language.PureScript.Types++instance Partial Type where+  unknown = TUnknown+  isUnknown (TUnknown u) = Just u+  isUnknown _ = Nothing+  unknowns = everythingOnTypes (++) go+    where+    go (TUnknown u) = [u]+    go _ = []+  ($?) sub = everywhereOnTypes go+    where+    go t@(TUnknown u) = fromMaybe t $ H.lookup u (runSubstitution sub)+    go other = other++instance Unifiable Check Type where+  (=?=) = unifyTypes++-- |+-- Unify two types, updating the current substitution+--+unifyTypes :: Type -> Type -> UnifyT Type Check ()+unifyTypes t1 t2 = rethrow (mkErrorStack ("Error unifying type " ++ prettyPrintType t1 ++ " with type " ++ prettyPrintType t2) Nothing <>) $+  unifyTypes' t1 t2+  where+  unifyTypes' (TUnknown u1) (TUnknown u2) | u1 == u2 = return ()+  unifyTypes' (TUnknown u) t = u =:= t+  unifyTypes' t (TUnknown u) = u =:= t+  unifyTypes' (SaturatedTypeSynonym name args) ty = do+    ty1 <- introduceSkolemScope <=< expandTypeSynonym name $ args+    ty1 `unifyTypes` ty+  unifyTypes' ty s@(SaturatedTypeSynonym _ _) = s `unifyTypes` ty+  unifyTypes' (ForAll ident1 ty1 sc1) (ForAll ident2 ty2 sc2) =+    case (sc1, sc2) of+      (Just sc1', Just sc2') -> do+        sko <- newSkolemConstant+        let sk1 = skolemize ident1 sko sc1' ty1+        let sk2 = skolemize ident2 sko sc2' ty2+        sk1 `unifyTypes` sk2+      _ -> error "Skolemized type variable was not given a scope"+  unifyTypes' (ForAll ident ty1 (Just sc)) ty2 = do+    sko <- newSkolemConstant+    let sk = skolemize ident sko sc ty1+    sk `unifyTypes` ty2+  unifyTypes' ForAll{} _ = throwError . strMsg $ "Skolem variable scope is unspecified"+  unifyTypes' ty f@ForAll{} = f `unifyTypes` ty+  unifyTypes' (TypeVar v1) (TypeVar v2) | v1 == v2 = return ()+  unifyTypes' (TypeConstructor c1) (TypeConstructor c2) =+    guardWith (strMsg ("Cannot unify " ++ show c1 ++ " with " ++ show c2 ++ ".")) (c1 == c2)+  unifyTypes' (TypeApp t3 t4) (TypeApp t5 t6) = do+    t3 `unifyTypes` t5+    t4 `unifyTypes` t6+  unifyTypes' (Skolem _ s1 _) (Skolem _ s2 _) | s1 == s2 = return ()+  unifyTypes' (KindedType ty1 _) ty2 = ty1 `unifyTypes` ty2+  unifyTypes' ty1 (KindedType ty2 _) = ty1 `unifyTypes` ty2+  unifyTypes' r1@RCons{} r2 = unifyRows r1 r2+  unifyTypes' r1 r2@RCons{} = unifyRows r1 r2+  unifyTypes' r1@REmpty r2 = unifyRows r1 r2+  unifyTypes' r1 r2@REmpty = unifyRows r1 r2+  unifyTypes' t@(ConstrainedType _ _) _ = throwError . strMsg $ "Attempted to unify a constrained type " ++ prettyPrintType t ++ " with another type."+  unifyTypes' t3 t4@(ConstrainedType _ _) = unifyTypes' t4 t3+  unifyTypes' t3 t4 = throwError . strMsg $ "Cannot unify " ++ prettyPrintType t3 ++ " with " ++ prettyPrintType t4 ++ "."++-- |+-- Unify two rows, updating the current substitution+--+-- Common labels are first identified, and unified. Remaining labels and types are unified with a+-- trailing row unification variable, if appropriate, otherwise leftover labels result in a unification+-- error.+--+unifyRows :: Type -> Type -> UnifyT Type Check ()+unifyRows r1 r2 =+  let+    (s1, r1') = rowToList r1+    (s2, r2') = rowToList r2+    int = [ (t1, t2) | (name, t1) <- s1, (name', t2) <- s2, name == name' ]+    sd1 = [ (name, t1) | (name, t1) <- s1, name `notElem` map fst s2 ]+    sd2 = [ (name, t2) | (name, t2) <- s2, name `notElem` map fst s1 ]+  in do+    forM_ int (uncurry (=?=))+    unifyRows' sd1 r1' sd2 r2'+  where+  unifyRows' :: [(String, Type)] -> Type -> [(String, Type)] -> Type -> UnifyT Type Check ()+  unifyRows' [] (TUnknown u) sd r = u =:= rowFromList (sd, r)+  unifyRows' sd r [] (TUnknown u) = u =:= rowFromList (sd, r)+  unifyRows' sd1 (TUnknown u1) sd2 (TUnknown u2) = do+    forM_ sd1 $ \(_, t) -> occursCheck u2 t+    forM_ sd2 $ \(_, t) -> occursCheck u1 t+    rest <- fresh+    u1 =:= rowFromList (sd2, rest)+    u2 =:= rowFromList (sd1, rest)+  unifyRows' [] REmpty [] REmpty = return ()+  unifyRows' [] (TypeVar v1) [] (TypeVar v2) | v1 == v2 = return ()+  unifyRows' [] (Skolem _ s1 _) [] (Skolem _ s2 _) | s1 == s2 = return ()+  unifyRows' sd3 r3 sd4 r4 = throwError . strMsg $ "Cannot unify (" ++ prettyPrintRow (rowFromList (sd3, r3)) ++ ") with (" ++ prettyPrintRow (rowFromList (sd4, r4)) ++ ")"++-- |+-- Check that two types unify+--+unifiesWith :: Environment -> Type -> Type -> Bool+unifiesWith _ (TUnknown u1) (TUnknown u2) | u1 == u2 = True+unifiesWith _ (Skolem _ s1 _) (Skolem _ s2 _) | s1 == s2 = True+unifiesWith _ (TypeVar v1) (TypeVar v2) | v1 == v2 = True+unifiesWith _ (TypeConstructor c1) (TypeConstructor c2) | c1 == c2 = True+unifiesWith e (TypeApp h1 t1) (TypeApp h2 t2) = unifiesWith e h1 h2 && unifiesWith e t1 t2+unifiesWith e (SaturatedTypeSynonym name args) t2 =+  case expandTypeSynonym' e name args of+    Left  _  -> False+    Right t1 -> unifiesWith e t1 t2+unifiesWith e t1 t2@(SaturatedTypeSynonym _ _) = unifiesWith e t2 t1+unifiesWith _ _ _ = False++-- |+-- Replace a single type variable with a new unification variable+--+replaceVarWithUnknown :: String -> Type -> UnifyT Type Check Type+replaceVarWithUnknown ident ty = do+  tu <- fresh+  return $ replaceTypeVars ident tu ty+  +-- |+-- Replace type wildcards with unknowns+--+replaceTypeWildcards :: Type -> UnifyT t Check Type+replaceTypeWildcards = everywhereOnTypesM replace+  where+  replace TypeWildcard = do+    u <- fresh'+    return $ TUnknown u+  replace other = return other++-- |+-- Replace outermost unsolved unification variables with named type variables+--+varIfUnknown :: Type -> Type+varIfUnknown ty =+  let unks = nub $ unknowns ty+      toName = (:) 't' . show+      ty' = everywhereOnTypes typeToVar ty+      typeToVar :: Type -> Type+      typeToVar (TUnknown u) = TypeVar (toName u)+      typeToVar t = t+  in mkForAll (sort . map toName $ unks) ty'
src/Language/PureScript/TypeClassDictionaries.hs view
@@ -64,3 +64,10 @@   -- A type class dictionary which is an alias for an imported dictionary from another module   --   | TCDAlias (Qualified Ident) deriving (Show, Eq, Data, Typeable)++-- |+-- Find the original dictionary which a type class dictionary in scope refers to+--+canonicalizeDictionary :: TypeClassDictionaryInScope -> Qualified Ident+canonicalizeDictionary (TypeClassDictionaryInScope { tcdType = TCDRegular, tcdName = nm }) = nm+canonicalizeDictionary (TypeClassDictionaryInScope { tcdType = TCDAlias nm }) = nm
src/Language/PureScript/Types.hs view
@@ -47,6 +47,10 @@   --   | TypeVar String   -- |+  -- A type wildcard, as would appear in a partial type synonym+  --+  | TypeWildcard+  -- |   -- A type constructor   --   | TypeConstructor (Qualified ProperName)@@ -214,6 +218,16 @@     in case qs of          [] -> constrained          qs' -> foldl (\ty' (q, sco) -> ForAll q ty' sco) constrained qs'++-- |+-- Check if a type contains wildcards+--+containsWildcards :: Type -> Bool+containsWildcards = everythingOnTypes (||) go+  where+  go :: Type -> Bool+  go TypeWildcard = True+  go _ = False  -- -- Traversals