packages feed

purescript 0.3.7 → 0.3.8.1

raw patch · 29 files changed

+795/−651 lines, 29 files

Files

libraries/prelude/prelude.purs view
@@ -6,29 +6,33 @@   foreign import data Array :: * -> *   foreign import data Function :: * -> * -> * -  id :: forall a. a -> a-  id = \x -> x-   flip :: forall a b c. (a -> b -> c) -> b -> a -> c-  flip = \f -> \b -> \a -> f a b+  flip f b a = f a b    konst :: forall a b. a -> b -> a-  konst = \a -> \b -> a+  konst a _ = a -  (|>) :: forall a b c. (a -> b) -> (b -> c) -> a -> c-  (|>) = \f -> \g -> \a -> g (f a)+  infixr 5 >>>+  infixr 5 <<< -  infixr 5 |>+  class Category a where+    id :: forall t. a t t+    (<<<) :: forall b c d. a c d -> a b c -> a b d+    (>>>) :: forall b c d. a b c -> a c d -> a b d -  (<|) :: forall a b c. (b -> c) -> (a -> b) -> a -> c-  (<|) = flip (|>)+  instance Category (->) where+    id x = x+    (<<<) f g x = f (g x)+    (>>>) f g x = g (f x) -  infixr 5 <|+  infixr 1000 $+  infixl 1000 #    ($) :: forall a b. (a -> b) -> a -> b   ($) f x = f x -  infixr 1000 $+  (#) :: forall a b. a -> (a -> b) -> b+  (#) x f = f x    class Show a where     show :: a -> String@@ -40,12 +44,292 @@     show true = "true"     show false = "false" +  foreign import showNumber "function showNumber(n) {\+                            \  return n.toString();\+                            \}" :: Number -> String++  instance Prelude.Show Number where+    show = showNumber++  class Read a where+    read :: String -> a++  instance Read String where+    read s = s++  instance Read Boolean where+    read "true" = true+    read _ = false+   class Monad m where     ret :: forall a. a -> m a     (>>=) :: forall a b. m a -> (a -> m b) -> m b +  infixl 5 *+  infixl 5 /+  infixl 5 %++  infixl 7 -+  infixl 7 +++  class Num a where+    (+) :: a -> a -> a+    (-) :: a -> a -> a+    (*) :: a -> a -> a+    (/) :: a -> a -> a+    (%) :: a -> a -> a+    negate :: a -> a++  foreign import numAdd "function numAdd(n1) {\+                        \  return function(n2) {\+                        \    return n1 + n2;\+                        \  };\+                        \}" :: Number -> Number -> Number++  foreign import numSub "function numSub(n1) {\+                        \  return function(n2) {\+                        \    return n1 - n2;\+                        \  };\+                        \}" :: Number -> Number -> Number++  foreign import numMul "function numMul(n1) {\+                        \  return function(n2) {\+                        \    return n1 * n2;\+                        \  };\+                        \}" :: Number -> Number -> Number++  foreign import numDiv "function numDiv(n1) {\+                        \  return function(n2) {\+                        \    return n1 / n2;\+                        \  };\+                        \}" :: Number -> Number -> Number++  foreign import numMod "function numMod(n1) {\+                        \  return function(n2) {\+                        \    return n1 % n2;\+                        \  };\+                        \}" :: Number -> Number -> Number++  foreign import numNegate "function numNegate(n) {\+                           \  return -n;\+                           \}" :: Number -> Number++  instance Num Number where+    (+) = numAdd+    (-) = numSub+    (*) = numMul+    (/) = numDiv+    (%) = numMod+    negate = numNegate++  infixl 9 ==+  infixl 9 /=++  class Eq a where+    (==) :: a -> a -> Boolean+    (/=) :: a -> a -> Boolean++  -- Referential equality+  data Ref a = Ref a++  foreign import refEq "function refEq(r1) {\+                       \  return function(r2) {\+                       \    return r1.value === r2.value;\+                       \  };\+                       \}" :: forall a. Ref a -> Ref a -> Boolean++  foreign import refIneq "function refIneq(r1) {\+                         \  return function(r2) {\+                         \    return r1.value !== r2.value;\+                         \  };\+                         \}" :: forall a. Ref a -> Ref a -> Boolean++  foreign import unsafeRefEq "function unsafeRefEq(r1) {\+                             \  return function(r2) {\+                             \    return r1 === r2;\+                             \  };\+                             \}" :: forall a. a -> a -> Boolean++  foreign import unsafeRefIneq "function unsafeRefIneq(r1) {\+                               \  return function(r2) {\+                               \    return r1 !== r2;\+                               \  };\+                               \}" :: forall a. a -> a -> Boolean++  instance Eq (Ref a) where+    (==) = refEq+    (/=) = refIneq++  instance Eq String where+    (==) = unsafeRefEq+    (/=) = unsafeRefIneq++  instance Eq Number where+    (==) = unsafeRefEq+    (/=) = unsafeRefIneq++  instance Eq Boolean where+    (==) = unsafeRefEq+    (/=) = unsafeRefIneq++  instance (Eq a) => Eq [a] where+    (==) [] [] = true+    (==) (x:xs) (y:ys) = x == y && xs == ys+    (==) _ _ = false+    (/=) xs ys = not (xs == ys)++  infixl 3 <+  infixl 3 >+  infixl 3 <=+  infixl 3 >=++  class Ord a where+    (<) :: a -> a -> Boolean+    (>) :: a -> a -> Boolean+    (<=) :: a -> a -> Boolean+    (>=) :: a -> a -> Boolean++  foreign import numLess "function numLess(n1) {\+                         \  return function(n2) {\+                         \    return n1 < n2;\+                         \  };\+                         \}" :: Number -> Number -> Boolean++  foreign import numLessEq "function numLessEq(n1) {\+                           \  return function(n2) {\+                           \    return n1 <= n2;\+                           \  };\+                           \}" :: Number -> Number -> Boolean++  foreign import numGreater "function numGreater(n1) {\+                            \  return function(n2) {\+                            \    return n1 > n2;\+                            \  };\+                            \}" :: Number -> Number -> Boolean++  foreign import numGreaterEq "function numGreaterEq(n1) {\+                              \  return function(n2) {\+                              \    return n1 >= n2;\+                              \  };\+                              \}" :: Number -> Number -> Boolean++  instance Ord Number where+    (<) = numLess+    (>) = numGreater+    (<=) = numLessEq+    (>=) = numGreaterEq++  infixl 10 &+  infixl 10 |+  infixl 10 ^++  class Bits b where+    (&) :: b -> b -> b+    (|) :: b -> b -> b+    (^) :: b -> b -> b+    shl :: b -> Number -> b+    shr :: b -> Number -> b+    zshr :: b -> Number -> b+    complement :: b -> b++  foreign import numShl "function numShl(n1) {\+                        \  return function(n2) {\+                        \    return n1 << n2;\+                        \  };\+                        \}" :: Number -> Number -> Number++  foreign import numShr "function numShr(n1) {\+                        \  return function(n2) {\+                        \    return n1 >> n2;\+                        \  };\+                        \}" :: Number -> Number -> Number++  foreign import numZshr "function numZshr(n1) {\+                          \  return function(n2) {\+                          \    return n1 >>> n2;\+                          \  };\+                          \}" :: Number -> Number -> Number++  foreign import numAnd "function numAnd(n1) {\+                        \  return function(n2) {\+                        \    return n1 & n2;\+                        \  };\+                        \}" :: Number -> Number -> Number++  foreign import numOr "function numOr(n1) {\+                       \  return function(n2) {\+                       \    return n1 | n2;\+                       \  };\+                       \}" :: Number -> Number -> Number++  foreign import numXor "function numXor(n1) {\+                        \  return function(n2) {\+                        \    return n1 ^ n2;\+                        \  };\+                        \}" :: Number -> Number -> Number++  foreign import numComplement "function numComplement(n) {\+                               \  return ~n;\+                               \}" :: Number -> Number++  instance Bits Number where+    (&) = numAnd+    (|) = numOr+    (^) = numXor+    shl = numShl+    shr = numShr+    zshr = numZshr+    complement = numComplement++  infixl 4 !!++  foreign import (!!) "function $bang$bang(xs) {\+                      \  return function(n) {\+                      \    return xs[n];\+                      \  };\+                      \}" :: forall a. [a] -> Number -> a++  infixr 11 ||+  infixr 11 &&++  class BoolLike b where+    (&&) :: b -> b -> b+    (||) :: b -> b -> b+    not :: b -> b++  foreign import boolAnd "function boolAnd(b1) {\+                         \  return function(b2) {\+                         \    return b1 && b2;\+                         \  };\+                         \}"  :: Boolean -> Boolean -> Boolean++  foreign import boolOr "function boolOr(b1) {\+                        \  return function(b2) {\+                        \    return b1 || b2;\+                        \  };\+                        \}" :: Boolean -> Boolean -> Boolean++  foreign import boolNot "function boolNot(b) {\+                         \  return !b;\+                         \}" :: Boolean -> Boolean++  instance BoolLike Boolean where+    (&&) = boolAnd+    (||) = boolOr+    not = boolNot++  infixr 6 ++++  foreign import (++) "function $plus$plus(s1) {\+                      \  return function(s2) {\+                      \    return s1 + s2;\+                      \  };\+                      \}" :: String -> String -> String+ module Maybe where +  import Prelude+   data Maybe a = Nothing | Just a    maybe :: forall a b. b -> (a -> b) -> Maybe a -> b@@ -53,7 +337,7 @@   maybe _ f (Just a) = f a    fromMaybe :: forall a. a -> Maybe a -> a-  fromMaybe a = maybe a Prelude.id+  fromMaybe a = maybe a (Prelude.id :: forall a. a -> a)    instance Prelude.Monad Maybe where     ret = Just@@ -65,11 +349,11 @@    either :: forall a b c. (a -> c) -> (b -> c) -> Either a b -> c   either f _ (Left a) = f a-  either _ g (Right b) = g b +  either _ g (Right b) = g b    instance Prelude.Monad (Either e) where     ret = Right-    (>>=) = either (\e _ -> Left e) (\a f -> f a) +    (>>=) = either (\e _ -> Left e) (\a f -> f a)  module Arrays where @@ -92,7 +376,7 @@    map :: forall a b. (a -> b) -> [a] -> [b]   map _ [] = []-  map f (x:xs) = f x : map f xs  +  map f (x:xs) = f x : map f xs    foldr :: forall a b. (a -> b -> a) -> a -> [b] -> a   foldr f a (b : bs) = f (foldr f a bs) b@@ -194,7 +478,7 @@    empty :: forall a. [a] -> Boolean   empty [] = true-  empty _ = false +  empty _ = false    range :: Number -> Number -> [Number]   range lo hi = {@@ -223,6 +507,7 @@  module Tuple where +  import Prelude   import Arrays    type Tuple a b = { fst :: a, snd :: b }@@ -234,7 +519,7 @@   uncurry f t = f t.fst t.snd    tuple :: forall a b. a -> b -> Tuple a b-  tuple = curry Prelude.id+  tuple = curry (\t -> t)    zip :: forall a b. [a] -> [b] -> [Tuple a b]   zip = zipWith tuple@@ -382,12 +667,6 @@                              \  };\                              \}" :: Number -> Number -> String -  foreign import numberToString "function numberToString(n) {\-                                \  return n.toString();\-                                \}" :: Number -> String--  foreign import isNaN :: Number -> Boolean-   foreign import isFinite :: Number -> Boolean    foreign import parseFloat :: String -> Number@@ -402,8 +681,7 @@    foreign import decodeURI :: String -> String -  instance Prelude.Show Number where-    show = numberToString+  foreign import isNaN :: Number -> Boolean  module Math where @@ -493,7 +771,7 @@                          \      return f(a())(); \                          \    }; \                          \  }; \-                         \}" :: forall e a b. Eff e a -> (a -> Eff e b) -> Eff e b +                         \}" :: forall e a b. Eff e a -> (a -> Eff e b) -> Eff e b    type Pure a = forall e. Eff e a @@ -544,11 +822,11 @@ module IORef where    import Eff-  +   foreign import data Ref :: !-  +   foreign import data IORef :: * -> *-  +   foreign import newIORef "function newIORef(val) {\                           \  return function () {\                           \    return { value: val };\@@ -582,9 +860,9 @@    import Prelude   import Eff-  +   foreign import data Trace :: !-  +   foreign import trace "function trace(s) { \                        \  return function() { \                        \    console.log(s); \@@ -593,7 +871,7 @@                        \}" :: forall r. String -> Eff (trace :: Trace | r) {}    print :: forall a r. (Prelude.Show a) => a -> Eff (trace :: Trace | r) {}-  print o = trace (show o) +  print o = trace (show o)  module ST where @@ -630,7 +908,7 @@                             \    };\                             \  };\                             \}" :: forall a h r. STRef h a -> a -> Eff (st :: ST h | r) {}-  +   foreign import runST "function runST(f) {\                        \  return f;\                        \}" :: forall a r. (forall h. Eff (st :: ST h | r) a) -> Eff r a
psc/Main.hs view
@@ -90,8 +90,12 @@ runMain = value $ flag $ (optInfo [ "run-main" ])      { optDoc = "Generate code to run the main method in the Main module." } +noOpts :: Term Bool+noOpts = value $ flag $ (optInfo [ "no-opts" ])+     { optDoc = "Skip the optimization phase." }+ options :: Term P.Options-options = P.Options <$> tco <*> performRuntimeTypeChecks <*> magicDo <*> runMain+options = P.Options <$> tco <*> performRuntimeTypeChecks <*> magicDo <*> runMain <*> noOpts  stdInOrInputFiles :: FilePath -> Term (Maybe [FilePath]) stdInOrInputFiles prelude = combine <$> useStdIn <*> (not <$> noPrelude) <*> inputFiles
psci/Main.hs view
@@ -35,7 +35,7 @@ getPreludeFilename = Paths.getDataFileName "libraries/prelude/prelude.purs"  options :: P.Options-options = P.Options True False True True+options = P.Options True False True True True  completion :: [P.Module] -> CompletionFunc IO completion ms = completeWord Nothing " \t\n\r" findCompletions
purescript.cabal view
@@ -1,5 +1,5 @@ name: purescript-version: 0.3.7+version: 0.3.8.1 cabal-version: >=1.8 build-type: Simple license: MIT@@ -36,6 +36,7 @@                      Language.PureScript.Sugar.Operators                      Language.PureScript.Sugar.TypeClasses                      Language.PureScript.CodeGen+                     Language.PureScript.CodeGen.Common                      Language.PureScript.CodeGen.Externs                      Language.PureScript.CodeGen.JS                      Language.PureScript.CodeGen.JS.AST
src/Language/PureScript.hs view
@@ -65,6 +65,6 @@               _ | optionsRunMain opts -> do                     when ((ModuleName (ProperName "Main"), Ident "main") `M.notMember` (names env)) $                       Left "Main.main is undefined"-                    return $ js ++ [JSApp (JSAccessor "main" (JSVar (Ident "Main"))) []]+                    return $ js ++ [JSApp (JSAccessor "main" (JSVar "Main")) []]                 | otherwise -> return js   return (prettyPrintJS js', exts, env)
+ src/Language/PureScript/CodeGen/Common.hs view
@@ -0,0 +1,56 @@+-----------------------------------------------------------------------------+--+-- Module      :  Language.PureScript.CodeGen.Common+-- Copyright   :  (c) Phil Freeman 2013+-- License     :  MIT+--+-- Maintainer  :  Phil Freeman <paf31@cantab.net>+-- Stability   :  experimental+-- Portability :+--+-- |+-- Common code generation utility functions+--+-----------------------------------------------------------------------------++module Language.PureScript.CodeGen.Common where++import Data.Char+import Language.PureScript.Names++-- |+-- Convert an Ident into a valid Javascript identifier:+--+--  * Alphanumeric characters are kept unmodified+--+--  * Symbols are encoded as a dollar symbol ($) followed by their ordinal value+--+identToJs :: Ident -> String+identToJs (Ident name) = concatMap identCharToString name+identToJs (Op op) = concatMap identCharToString op+identToJs (Escaped name) = name++identCharToString :: Char -> String+identCharToString c | isAlphaNum c = [c]+identCharToString '_' = "_"+identCharToString '.' = "$dot"+identCharToString '$' = "$dollar"+identCharToString '~' = "$tilde"+identCharToString '=' = "$eq"+identCharToString '<' = "$less"+identCharToString '>' = "$greater"+identCharToString '!' = "$bang"+identCharToString '#' = "$hash"+identCharToString '%' = "$percent"+identCharToString '^' = "$up"+identCharToString '&' = "$amp"+identCharToString '|' = "$bar"+identCharToString '*' = "$times"+identCharToString '/' = "$div"+identCharToString '+' = "$plus"+identCharToString '-' = "$minus"+identCharToString ':' = "$colon"+identCharToString '\\' = "$bslash"+identCharToString '?' = "$qmark"+identCharToString '@' = "$at"+identCharToString c = '$' : show (ord c)
src/Language/PureScript/CodeGen/JS.hs view
@@ -41,6 +41,7 @@ import Language.PureScript.CodeGen.JS.AST as AST import Language.PureScript.Types import Language.PureScript.CodeGen.Optimize+import Language.PureScript.CodeGen.Common (identToJs) import Language.PureScript.TypeChecker.Monad (canonicalizeDataConstructor)  -- |@@ -48,79 +49,77 @@ -- moduleToJs :: Options -> Module -> Environment -> [JS] moduleToJs opts (Module pname@(ProperName name) decls) env =-  [ JSVariableIntroduction (Ident name) Nothing-  , JSApp (JSFunction Nothing [Ident name]-                      (JSBlock (concat $ mapMaybe (\decl -> fmap (map $ optimize opts) $ declToJs opts (ModuleName pname) decl env) (sortBy typeClassesLast decls))))-          [JSAssignment (JSAssignVariable (Ident name))-                         (JSBinary Or (JSVar (Ident name)) (JSObjectLiteral []))]+  [ JSVariableIntroduction name Nothing+  , JSApp (JSFunction Nothing [name]+                      (JSBlock (concat $ mapMaybe (\decl -> fmap (map $ optimize opts) $ declToJs opts (ModuleName pname) decl env) (decls))))+          [JSAssignment (JSVar name)+                        (JSBinary Or (JSVar name) (JSObjectLiteral []))]   ]-  where-  typeClassesLast (ExternDeclaration TypeClassDictionaryImport _ _ _) (ExternDeclaration TypeClassDictionaryImport _ _ _) = EQ-  typeClassesLast (ExternDeclaration TypeClassDictionaryImport _ _ _) _ = GT-  typeClassesLast _ (ExternDeclaration TypeClassDictionaryImport _ _ _) = LT-  typeClassesLast _ _ = EQ  -- | -- Generate code in the simplified Javascript intermediate representation for a declaration -- declToJs :: Options -> ModuleName -> Declaration -> Environment -> Maybe [JS] declToJs opts mp (ValueDeclaration ident _ _ val) e =-  Just [ JSVariableIntroduction ident (Just (valueToJs opts mp e val)),-         setProperty (identToJs ident) (JSVar ident) mp ]+  Just $ JSVariableIntroduction (identToJs ident) (Just (valueToJs opts mp e val))+         : setProperty ident (var ident) mp declToJs opts mp (BindingGroupDeclaration vals) e =   Just $ concatMap (\(ident, val) ->-           [ JSVariableIntroduction ident (Just (valueToJs opts mp e val)),-             setProperty (identToJs ident) (JSVar ident) mp ]+           JSVariableIntroduction (identToJs ident) (Just (valueToJs opts mp e val))+           : setProperty ident (var ident) mp          ) vals declToJs _ mp (DataDeclaration _ _ ctors) _ =   Just $ flip concatMap ctors $ \(pn@(ProperName ctor), maybeTy) ->     let       ctorJs =         case maybeTy of-          Nothing -> JSVariableIntroduction (Ident ctor) (Just (JSObjectLiteral [ ("ctor", JSStringLiteral (show (Qualified (Just mp) pn))) ]))-          Just _ -> JSFunction (Just (Ident ctor)) [Ident "value"]+          Nothing -> JSVariableIntroduction ctor (Just (JSObjectLiteral [ ("ctor", JSStringLiteral (show (Qualified (Just mp) pn))) ]))+          Just _ -> JSFunction (Just ctor) ["value"]                       (JSBlock [JSReturn                         (JSObjectLiteral [ ("ctor", JSStringLiteral (show (Qualified (Just mp) pn)))-                                         , ("value", JSVar (Ident "value")) ])])-    in [ ctorJs, setProperty ctor (JSVar (Ident ctor)) mp ]+                                         , ("value", JSVar "value") ])])+    in ctorJs : setProperty (Escaped ctor) (JSVar ctor) mp declToJs opts mp (DataBindingGroupDeclaration ds) e =   Just $ concat $ mapMaybe (flip (declToJs opts mp) e) ds declToJs _ mp (ExternDeclaration importTy ident (Just js) _) _ =-  Just [ js-       , setProperty (identToJs ident) (JSVar ident) mp ]+  Just $ js : setProperty ident (var ident) mp declToJs _ _ _ _ = Nothing -setProperty :: String -> JS -> ModuleName -> JS-setProperty prop val (ModuleName (ProperName moduleName)) = JSAssignment (JSAssignProperty prop (JSAssignVariable (Ident moduleName))) val+setProperty :: Ident -> JS -> ModuleName -> [JS]+setProperty ident@(Op op) val (ModuleName (ProperName moduleName)) =+  [ JSAssignment (JSAccessor (identToJs ident) (JSVar moduleName)) val+  , JSAssignment (JSIndexer (JSStringLiteral op) (JSVar moduleName)) (JSAccessor (identToJs ident) (JSVar moduleName)) ]+setProperty ident val (ModuleName (ProperName moduleName)) =+  [ JSAssignment (JSAccessor (identToJs ident) (JSVar moduleName)) val ] +var :: Ident -> JS+var = JSVar . identToJs+ valueToJs :: Options -> ModuleName -> Environment -> Value -> JS valueToJs _ _ _ (NumericLiteral n) = JSNumericLiteral n valueToJs _ _ _ (StringLiteral s) = JSStringLiteral s valueToJs _ _ _ (BooleanLiteral b) = JSBooleanLiteral b valueToJs opts m e (ArrayLiteral xs) = JSArrayLiteral (map (valueToJs opts m e) xs) valueToJs opts m e (ObjectLiteral ps) = JSObjectLiteral (map (second (valueToJs opts m e)) ps)-valueToJs opts m e (ObjectUpdate o ps) = JSApp (JSAccessor "extend" (JSVar (Ident "Object"))) [ valueToJs opts m e o, JSObjectLiteral (map (second (valueToJs opts m e)) ps)]+valueToJs opts m e (ObjectUpdate o ps) = JSApp (JSAccessor "extend" (JSVar "Object")) [ valueToJs opts m e o, JSObjectLiteral (map (second (valueToJs opts m e)) ps)] valueToJs _ m e (Constructor (Qualified Nothing name)) =   case M.lookup (m, name) (dataConstructors e) of     Just (_, Alias aliasModule aliasIdent) -> qualifiedToJS identToJs (Qualified (Just aliasModule) aliasIdent)-    _ -> JSVar . Ident . runProperName $ name+    _ -> JSVar . runProperName $ name valueToJs _ _ _ (Constructor name) = qualifiedToJS runProperName name valueToJs opts m e (Block sts) = JSApp (JSFunction Nothing [] (JSBlock (map (statementToJs opts m e) sts))) [] valueToJs opts m e (Case values binders) = bindersToJs opts m e binders (map (valueToJs opts m e) values) valueToJs opts m e (IfThenElse cond th el) = JSConditional (valueToJs opts m e cond) (valueToJs opts m e th) (valueToJs opts m e el) valueToJs opts m e (Accessor prop val) = JSAccessor prop (valueToJs opts m e val)-valueToJs opts m e (Indexer index val) = JSIndexer (valueToJs opts m e index) (valueToJs opts m e val) valueToJs opts m e (App val arg) = JSApp (valueToJs opts m e val) [valueToJs opts m e arg]-valueToJs opts m e (Abs arg val) = JSFunction Nothing [arg] (JSBlock [JSReturn (valueToJs opts m e val)])-valueToJs opts m e (TypedValue _ (Abs arg val) ty) | optionsPerformRuntimeTypeChecks opts = JSFunction Nothing [arg] (JSBlock $ runtimeTypeChecks arg ty ++ [JSReturn (valueToJs opts m e val)])-valueToJs opts m e (Unary op val) = JSUnary op (valueToJs opts m e val)-valueToJs opts m e (Binary op v1 v2) = JSBinary op (valueToJs opts m e v1) (valueToJs opts m e v2)+valueToJs opts m e (Abs arg val) = JSFunction Nothing [identToJs arg] (JSBlock [JSReturn (valueToJs opts m e val)])+valueToJs opts m e (TypedValue _ (Abs arg val) ty) | optionsPerformRuntimeTypeChecks opts = let arg' = identToJs arg in JSFunction Nothing [arg'] (JSBlock $ runtimeTypeChecks arg' ty ++ [JSReturn (valueToJs opts m e val)]) valueToJs _ m e (Var ident) = varToJs m e ident valueToJs opts m e (TypedValue _ val _) = valueToJs opts m e val valueToJs _ _ _ (TypeClassDictionary _ _) = error "Type class dictionary was not replaced" valueToJs _ _ _ _ = error "Invalid argument to valueToJs" -runtimeTypeChecks :: Ident -> Type -> [JS]+runtimeTypeChecks :: String -> Type -> [JS] runtimeTypeChecks arg ty =   let     argTy = getFunctionArgumentType ty@@ -147,16 +146,18 @@   typeCheck :: JS -> String -> JS   typeCheck js ty' = JSIfElse (JSBinary NotEqualTo (JSTypeOf js) (JSStringLiteral ty')) (JSBlock [JSThrow (JSStringLiteral $ ty' ++ " expected")]) Nothing   arrayCheck :: JS -> JS-  arrayCheck js = JSIfElse (JSUnary Not (JSApp (JSAccessor "isArray" (JSVar (Ident "Array"))) [js])) (JSBlock [JSThrow (JSStringLiteral "Array expected")]) Nothing+  arrayCheck js = JSIfElse (JSUnary Not (JSApp (JSAccessor "isArray" (JSVar "Array")) [js])) (JSBlock [JSThrow (JSStringLiteral "Array expected")]) Nothing  varToJs :: ModuleName -> Environment -> Qualified Ident -> JS-varToJs m e qual@(Qualified _ ident) = case M.lookup (qualify m qual) (names e) of-  Just (_, ty) | isExtern ty -> JSVar ident-  Just (_, Alias aliasModule aliasIdent) -> qualifiedToJS identToJs (Qualified (Just aliasModule) aliasIdent)-  _ -> case qual of-         Qualified Nothing _ -> JSVar ident-         _ -> qualifiedToJS identToJs qual+varToJs m e qual@(Qualified _ ident) = go qual   where+  go qual = case M.lookup (qualify m qual) (names e) of+    Just (_, ty) | isExtern ty -> var ident+    Just (_, Alias aliasModule aliasIdent) -> go (Qualified (Just aliasModule) aliasIdent)+    _ -> case qual of+           Qualified Nothing _ -> var ident+           Qualified (Just (ModuleName (ProperName mn))) (Op op) -> JSIndexer (JSStringLiteral op) (JSVar mn)+           _ -> qualifiedToJS identToJs qual   isExtern (Extern ForeignImport) = True   isExtern (Alias m' ident') = case M.lookup (m', ident') (names e) of     Just (_, ty') -> isExtern ty'@@ -164,17 +165,17 @@   isExtern _ = False  qualifiedToJS :: (a -> String) -> Qualified a -> JS-qualifiedToJS f (Qualified (Just (ModuleName (ProperName m))) a) = JSAccessor (f a) (JSVar (Ident m))-qualifiedToJS f (Qualified Nothing a) = JSVar (Ident (f a))+qualifiedToJS f (Qualified (Just (ModuleName (ProperName m))) a) = JSAccessor (f a) (JSVar m)+qualifiedToJS f (Qualified Nothing a) = JSVar (f a)  bindersToJs :: Options -> ModuleName -> Environment -> [([Binder], Maybe Guard, Value)] -> [JS] -> JS-bindersToJs opts m e binders vals = runGen (unusedNames (binders, vals)) $ do+bindersToJs opts m e binders vals = runGen (map identToJs (unusedNames (binders, vals))) $ do   valNames <- replicateM (length vals) fresh   jss <- forM binders $ \(bs, grd, result) -> go valNames [JSReturn (valueToJs opts m e result)] bs grd   return $ JSApp (JSFunction Nothing valNames (JSBlock (concat jss ++ [JSThrow (JSStringLiteral "Failed pattern match")])))                  vals   where-    go :: [Ident] -> [JS] -> [Binder] -> Maybe Guard -> Gen [JS]+    go :: [String] -> [JS] -> [Binder] -> Maybe Guard -> Gen [JS]     go _ done [] Nothing = return done     go _ done [] (Just cond) = return [JSIfElse (valueToJs opts m e cond) (JSBlock done) Nothing]     go (v:vs) done' (b:bs) grd = do@@ -182,7 +183,7 @@       binderToJs m e v done'' b     go _ _ _ _ = error "Invalid arguments to bindersToJs" -binderToJs :: ModuleName -> Environment -> Ident -> [JS] -> Binder -> Gen [JS]+binderToJs :: ModuleName -> Environment -> String -> [JS] -> Binder -> Gen [JS] binderToJs _ _ _ done NullBinder = return done binderToJs _ _ varName done (StringBinder str) =   return [JSIfElse (JSBinary EqualTo (JSVar varName) (JSStringLiteral str)) (JSBlock done) Nothing]@@ -193,7 +194,7 @@ binderToJs _ _ varName done (BooleanBinder False) =   return [JSIfElse (JSUnary Not (JSVar varName)) (JSBlock done) Nothing] binderToJs _ _ varName done (VarBinder ident) =-  return (JSVariableIntroduction ident (Just (JSVar varName)) : done)+  return (JSVariableIntroduction (identToJs ident) (Just (JSVar varName)) : done) binderToJs m e varName done (NullaryBinder ctor) =   if isOnlyConstructor m e ctor   then@@ -243,7 +244,7 @@     )) Nothing] binderToJs m e varName done (NamedBinder ident binder) = do   js <- binderToJs m e varName done binder-  return (JSVariableIntroduction ident (Just (JSVar varName)) : js)+  return (JSVariableIntroduction (identToJs ident) (Just (JSVar varName)) : js)  isOnlyConstructor :: ModuleName -> Environment -> Qualified ProperName -> Bool isOnlyConstructor m e ctor =@@ -258,10 +259,10 @@   typeConstructor fn = error $ "Invalid arguments to typeConstructor: " ++ show fn  statementToJs :: Options -> ModuleName -> Environment -> Statement -> JS-statementToJs opts m e (VariableIntroduction ident value) = JSVariableIntroduction ident (Just (valueToJs opts m e value))-statementToJs opts m e (Assignment target value) = JSAssignment (JSAssignVariable target) (valueToJs opts m e value)+statementToJs opts m e (VariableIntroduction ident value) = JSVariableIntroduction (identToJs ident) (Just (valueToJs opts m e value))+statementToJs opts m e (Assignment target value) = JSAssignment (JSVar (identToJs target)) (valueToJs opts m e value) statementToJs opts m e (While cond sts) = JSWhile (valueToJs opts m e cond) (JSBlock (map (statementToJs opts m e) sts))-statementToJs opts m e (For ident start end sts) = JSFor ident (valueToJs opts m e start) (valueToJs opts m e end) (JSBlock (map (statementToJs opts m e) sts))+statementToJs opts m e (For ident start end sts) = JSFor (identToJs ident) (valueToJs opts m e start) (valueToJs opts m e end) (JSBlock (map (statementToJs opts m e) sts)) statementToJs opts m e (If ifst) = ifToJs ifst   where   ifToJs :: IfStatement -> JS
src/Language/PureScript/CodeGen/JS/AST.hs view
@@ -17,12 +17,113 @@  module Language.PureScript.CodeGen.JS.AST where -import Language.PureScript.Names-import Language.PureScript.Values- import Data.Data ++ -- |+-- Built-in unary operators+--+data UnaryOperator+  -- |+  -- Numeric negation+  --+  = Negate+  -- |+  -- Boolean negation+  --+  | Not+  -- |+  -- Bitwise negation+  --+  | BitwiseNot+  -- |+  -- Numeric unary \'plus\'+  --+  | Positive deriving (Show, Eq, Data, Typeable)++-- |+-- Built-in binary operators+--+data BinaryOperator+  -- |+  -- Numeric addition+  --+  = Add+  -- |+  -- Numeric subtraction+  --+  | Subtract+  -- |+  -- Numeric multiplication+  --+  | Multiply+  -- |+  -- Numeric division+  --+  | Divide+  -- |+  -- Remainder+  --+  | Modulus+  -- |+  -- Generic equality test+  --+  | EqualTo+  -- |+  -- Generic inequality test+  --+  | NotEqualTo+  -- |+  -- Numeric less-than+  --+  | LessThan+  -- |+  -- Numeric less-than-or-equal+  --+  | LessThanOrEqualTo+  -- |+  -- Numeric greater-than+  --+  | GreaterThan+  -- |+  -- Numeric greater-than-or-equal+  --+  | GreaterThanOrEqualTo+  -- |+  -- Boolean and+  --+  | And+  -- |+  -- Boolean or+  --+  | Or+  -- |+  -- Bitwise and+  --+  | BitwiseAnd+  -- |+  -- Bitwise or+  --+  | BitwiseOr+  -- |+  -- Bitwise xor+  --+  | BitwiseXor+  -- |+  -- Bitwise left shift+  --+  | ShiftLeft+  -- |+  -- Bitwise right shift+  --+  | ShiftRight+  -- |+  -- Bitwise right shift with zero-fill+  --+  | ZeroFillShiftRight deriving (Show, Eq, Data, Typeable)++-- | -- Data type for simplified Javascript expressions -- data JS@@ -65,7 +166,7 @@   -- |   -- A function introduction (optional name, arguments, body)   ---  | JSFunction (Maybe Ident) [Ident] JS+  | JSFunction (Maybe String) [String] JS   -- |   -- Function application   --@@ -73,7 +174,7 @@   -- |   -- Variable   ---  | JSVar Ident+  | JSVar String   -- |   -- Conditional expression   --@@ -85,11 +186,11 @@   -- |   -- A variable introduction and optional initialization   ---  | JSVariableIntroduction Ident (Maybe JS)+  | JSVariableIntroduction String (Maybe JS)   -- |   -- A variable assignment   ---  | JSAssignment JSAssignment JS+  | JSAssignment JS JS   -- |   -- While loop   --@@ -97,7 +198,7 @@   -- |   -- For loop   ---  | JSFor Ident JS JS JS+  | JSFor String JS JS JS   -- |   -- If-then-else statement   --@@ -130,16 +231,3 @@   -- Raw Javascript (generated when parsing fails for an inline foreign import declaration)   --   | JSRaw String deriving (Show, Eq, Data, Typeable)---- |--- Data type for expressions which can appear on the left hand side of an assignment----data JSAssignment-  -- |-  -- Assign a variable-  ---  = JSAssignVariable Ident-  -- |-  -- Assign an object property-  ---  | JSAssignProperty String JSAssignment deriving (Show, Eq, Data, Typeable)
src/Language/PureScript/CodeGen/Monad.hs view
@@ -26,18 +26,18 @@ -- | -- Code generation monad data type ---newtype Gen a = Gen { unGen :: State [Ident] a } deriving (Functor, Applicative, Monad, MonadState [Ident])+newtype Gen a = Gen { unGen :: State [String] a } deriving (Functor, Applicative, Monad, MonadState [String])  -- | -- Run a computation in the code generation monad ---runGen :: [Ident] -> Gen a -> a+runGen :: [String] -> Gen a -> a runGen names = flip evalState names . unGen  -- | -- Generate a fresh name ---fresh :: Gen Ident+fresh :: Gen String fresh = do   (s:ss) <- get   put ss
src/Language/PureScript/CodeGen/Optimize.hs view
@@ -27,8 +27,10 @@ -- --  * Inlining variables -----  * Inline Prelude.($)+--  * Inline Prelude.($), Prelude.(#), Prelude.(++), Prelude.(!!) --+--  * Inlining primitive Javascript operators+-- -----------------------------------------------------------------------------  module Language.PureScript.CodeGen.Optimize (@@ -42,16 +44,17 @@ import Language.PureScript.Names import Language.PureScript.CodeGen.JS.AST import Language.PureScript.Options-import Language.PureScript.Pretty.Common (identToJs)+import Language.PureScript.CodeGen.Common (identToJs) import Language.PureScript.Sugar.TypeClasses        (mkDictionaryValueName)-import Language.PureScript.Types (Type(..))+import Language.PureScript.Types  -- | -- Apply a series of optimizer passes to simplified Javascript code -- optimize :: Options -> JS -> JS-optimize opts = untilFixedPoint $ applyAll+optimize opts | optionsNoOptimizations opts = id+              | otherwise = untilFixedPoint $ applyAll   [ collapseNestedBlocks   , tco opts   , magicDo opts@@ -59,7 +62,11 @@   , unThunk   , etaConvert   , inlineVariables-  , inlineDollar ]+  , inlineOperator "$" $ \f x -> JSApp f [x]+  , inlineOperator "#" $ \x f -> JSApp f [x]+  , inlineOperator "!!" $ flip JSIndexer+  , inlineOperator "++" $ JSBinary Add+  , inlineCommonOperators ]  applyAll :: [a -> a] -> a -> a applyAll = foldl1 (.)@@ -70,19 +77,19 @@   go a' = let a'' = f a' in           if a'' == a' then a'' else go a'' -replaceIdent :: (Data d) => Ident -> JS -> d -> d+replaceIdent :: (Data d) => String -> JS -> d -> d replaceIdent var1 js = everywhere (mkT replace)   where   replace (JSVar var2) | var1 == var2 = js   replace other = other -replaceIdents :: (Data d) => [(Ident, JS)] -> d -> d+replaceIdents :: (Data d) => [(String, JS)] -> d -> d replaceIdents vars = everywhere (mkT replace)   where   replace v@(JSVar var) = fromMaybe v $ lookup var vars   replace other = other -isReassigned :: (Data d) => Ident -> d -> Bool+isReassigned :: (Data d) => String -> d -> Bool isReassigned var1 = everything (||) (mkQ False check)   where   check :: JS -> Bool@@ -97,7 +104,7 @@   variablesOf (JSIndexer index val) = variablesOf index ++ variablesOf val   variablesOf _ = [] -isUsed :: (Data d) => Ident -> d -> Bool+isUsed :: (Data d) => String -> d -> Bool isUsed var1 = everything (||) (mkQ False check)   where   check :: JS -> Bool@@ -105,11 +112,13 @@   check (JSAssignment target _) | var1 == targetVariable target = True   check _ = False -targetVariable :: JSAssignment -> Ident-targetVariable (JSAssignVariable var) = var-targetVariable (JSAssignProperty _ tgt) = targetVariable tgt+targetVariable :: JS -> String+targetVariable (JSVar var) = var+targetVariable (JSAccessor _ tgt) = targetVariable tgt+targetVariable (JSIndexer _ tgt) = targetVariable tgt+targetVariable _ = error "Invalid argument to targetVariable" -isUpdated :: (Data d) => Ident -> d -> Bool+isUpdated :: (Data d) => String -> d -> Bool isUpdated var1 = everything (||) (mkQ False check)   where   check :: JS -> Bool@@ -173,12 +182,10 @@   where   tcoLabel :: String   tcoLabel = "tco"-  tcoVar :: Ident -> Ident-  tcoVar (Ident arg) = Ident $ "__tco_" ++ arg-  tcoVar _ = error "Invalid name in tcoVar"-  copyVar :: Ident -> Ident-  copyVar (Ident arg) = Ident $ "__copy_" ++ arg-  copyVar _ = error "Invalid name in copyVar"+  tcoVar :: String -> String+  tcoVar arg = "__tco_" ++ arg+  copyVar :: String -> String+  copyVar arg = "__copy_" ++ arg   convert :: JS -> JS   convert js@(JSVariableIntroduction name (Just fn@(JSFunction _ _ _))) =     let@@ -191,7 +198,7 @@               JSVariableIntroduction name (Just (replace (toLoop name allArgs body')))         | otherwise -> js   convert js = js-  collectAllFunctionArgs :: [[Ident]] -> (JS -> JS) -> JS -> ([[Ident]], JS, JS -> JS)+  collectAllFunctionArgs :: [[String]] -> (JS -> JS) -> JS -> ([[String]], JS, JS -> JS)   collectAllFunctionArgs allArgs f (JSFunction ident args (JSBlock (body@(JSReturn _):_))) =     collectAllFunctionArgs (args : allArgs) (\b -> f (JSFunction ident (map copyVar args) (JSBlock [b]))) body   collectAllFunctionArgs allArgs f (JSFunction ident args body@(JSBlock _)) =@@ -201,7 +208,7 @@   collectAllFunctionArgs allArgs f (JSReturn (JSFunction ident args body@(JSBlock _))) =     (args : allArgs, body, \b -> f (JSReturn (JSFunction ident (map copyVar args) b)))   collectAllFunctionArgs allArgs f body = (allArgs, body, f)-  isTailCall :: Ident -> JS -> Bool+  isTailCall :: String -> JS -> Bool   isTailCall ident js =     let       numSelfCalls = everything (+) (mkQ 0 countSelfCalls) js@@ -220,7 +227,7 @@     countSelfCallsInTailPosition _ = 0     countSelfCallsUnderFunctions (JSFunction _ _ js') = everything (+) (mkQ 0 countSelfCalls) js'     countSelfCallsUnderFunctions _ = 0-  toLoop :: Ident -> [Ident] -> JS -> JS+  toLoop :: String -> [String] -> JS -> JS   toLoop ident allArgs js = JSBlock $         map (\arg -> JSVariableIntroduction arg (Just (JSVar (copyVar arg)))) allArgs ++         [ JSLabel tcoLabel $ JSWhile (JSBooleanLiteral True) (JSBlock [ everywhere (mkT loopify) js ]) ]@@ -233,13 +240,13 @@         JSBlock $ zipWith (\val arg ->                     JSVariableIntroduction (tcoVar arg) (Just val)) allArgumentValues allArgs                   ++ map (\arg ->-                    JSAssignment (JSAssignVariable arg) (JSVar (tcoVar arg))) allArgs+                    JSAssignment (JSVar arg) (JSVar (tcoVar arg))) allArgs                   ++ [ JSContinue tcoLabel ]     loopify other = other     collectSelfCallArgs :: [[JS]] -> JS -> [[JS]]     collectSelfCallArgs allArgumentValues (JSApp fn args') = collectSelfCallArgs (args' : allArgumentValues) fn     collectSelfCallArgs allArgumentValues _ = allArgumentValues-  isSelfCall :: Ident -> JS -> Bool+  isSelfCall :: String -> JS -> Bool   isSelfCall ident (JSApp (JSVar ident') _) | ident == ident' = True   isSelfCall ident (JSApp fn _) = isSelfCall ident fn   isSelfCall _ _ = False@@ -251,23 +258,24 @@ magicDo' :: JS -> JS magicDo' = everywhere (mkT undo) . everywhere' (mkT convert)   where-  fnName = Ident "__do"+  fnName = "__do"   convert :: JS -> JS   convert (JSApp (JSApp ret [val]) []) | isReturn ret = val-  convert (JSApp (JSApp bind [m]) [JSFunction Nothing [Ident "_"] (JSBlock [JSReturn ret])]) | isBind bind =+  convert (JSApp (JSApp bind [m]) [JSFunction Nothing ["_"] (JSBlock [JSReturn ret])]) | isBind bind =     JSFunction (Just fnName) [] $ JSBlock [ JSApp m [], JSReturn (JSApp ret []) ]   convert (JSApp (JSApp bind [m]) [JSFunction Nothing [arg] (JSBlock [JSReturn ret])]) | isBind bind =     JSFunction (Just fnName) [] $ JSBlock [ JSVariableIntroduction arg (Just (JSApp m [])), JSReturn (JSApp ret []) ]   convert other = other-  isBind (JSApp bindPoly [JSApp effDict []]) | isBindPoly bindPoly && isEffDict effDict = True+  isBind (JSApp bindPoly [effDict]) | isBindPoly bindPoly && isEffDict effDict = True   isBind _ = False-  isReturn (JSApp retPoly [JSApp effDict []]) | isRetPoly retPoly && isEffDict effDict = True+  isReturn (JSApp retPoly [effDict]) | isRetPoly retPoly && isEffDict effDict = True   isReturn _ = False-  isBindPoly (JSVar (Op ">>=")) = True-  isBindPoly (JSAccessor prop (JSVar (Ident "Prelude"))) | prop == identToJs (Op ">>=") = True+  isBindPoly (JSVar op) | op == identToJs (Op ">>=") = True+  isBindPoly (JSAccessor prop (JSVar "Prelude")) | prop == identToJs (Op ">>=") = True+  isBindPoly (JSIndexer (JSStringLiteral ">>=") (JSVar "Prelude")) = True   isBindPoly _ = False-  isRetPoly (JSVar (Ident "ret")) = True-  isRetPoly (JSAccessor "ret" (JSVar (Ident "Prelude"))) = True+  isRetPoly (JSVar "ret") = True+  isRetPoly (JSAccessor "ret" (JSVar "Prelude")) = True   isRetPoly _ = False   prelude = ModuleName (ProperName "Prelude")   effModule = ModuleName (ProperName "Eff")@@ -275,8 +283,8 @@     effModule     (Qualified (Just prelude) (ProperName "Monad"))     (TypeConstructor (Qualified (Just effModule) (ProperName "Eff")))-  isEffDict (JSVar (Ident ident)) | ident == effDictName = True-  isEffDict (JSAccessor prop (JSVar (Ident "Eff"))) | prop == effDictName = True+  isEffDict (JSVar ident) | ident == effDictName = True+  isEffDict (JSAccessor prop (JSVar "Eff")) | prop == effDictName = True   isEffDict _ = False   undo :: JS -> JS   undo (JSReturn (JSApp (JSFunction (Just ident) [] body) [])) | ident == fnName = body@@ -292,11 +300,79 @@   go (JSBlock sts) = sts   go s = [s] -inlineDollar :: JS -> JS-inlineDollar = everywhere (mkT convert)+inlineOperator :: String -> (JS -> JS -> JS) -> JS -> JS+inlineOperator op f = everywhere (mkT convert)   where   convert :: JS -> JS-  convert (JSApp (JSApp dollar [f]) [x]) | isDollar dollar = JSApp f [x]+  convert (JSApp (JSApp op [x]) [y]) | isOp op = f x y   convert other = other-  isDollar (JSAccessor name (JSVar (Ident "Prelude"))) | name == identToJs (Op "$") = True-  isDollar _ = False+  isOp (JSAccessor longForm (JSVar "Prelude")) | longForm == identToJs (Op op) = True+  isOp (JSIndexer (JSStringLiteral op') (JSVar "Prelude")) | op == op' = True+  isOp _ = False++inlineCommonOperators :: JS -> JS+inlineCommonOperators = applyAll+  [ binary "+" "Num" tyNumber Add+  , binary "-" "Num" tyNumber Subtract+  , binary "*" "Num" tyNumber Multiply+  , binary "/" "Num" tyNumber Divide+  , binary "%" "Num" tyNumber Modulus+  , unary "negate" "Num" tyNumber Negate++  , binary "<" "Ord" tyNumber LessThan+  , binary ">" "Ord" tyNumber GreaterThan+  , binary "<=" "Ord" tyNumber LessThanOrEqualTo+  , binary ">=" "Ord" tyNumber GreaterThanOrEqualTo++  , binary "==" "Eq" tyNumber EqualTo+  , binary "/=" "Eq" tyNumber NotEqualTo+  , binary "==" "Eq" tyString EqualTo+  , binary "/=" "Eq" tyString NotEqualTo+  , binary "==" "Eq" tyBoolean EqualTo+  , binary "/=" "Eq" tyBoolean NotEqualTo++  , binaryFunction "shl" "Bits" tyNumber ShiftLeft+  , binaryFunction "shr" "Bits" tyNumber ShiftRight+  , binaryFunction "zshr" "Bits" tyNumber ZeroFillShiftRight+  , binary "&" "Bits" tyNumber BitwiseAnd+  , binary "|" "Bits" tyNumber BitwiseOr+  , binary "^" "Bits" tyNumber BitwiseXor+  , unary "complement" "Bits" tyNumber BitwiseNot++  , binary "&&" "BoolLike" tyBoolean And+  , binary "||" "BoolLike" tyBoolean Or+  , unary "not" "BoolLike" tyBoolean Not+  ]+  where+  binary :: String -> String -> Type -> BinaryOperator -> JS -> JS+  binary opString className classTy op = everywhere (mkT convert)+    where+    convert :: JS -> JS+    convert (JSApp (JSApp (JSApp fn [dict]) [x]) [y]) | isOp fn && isOpDict className classTy dict = JSBinary op x y+    convert other = other+    isOp (JSAccessor longForm (JSVar "Prelude")) | longForm == identToJs (Op opString) = True+    isOp (JSIndexer (JSStringLiteral op') (JSVar "Prelude")) | opString == op' = True+    isOp _ = False+  binaryFunction :: String -> String -> Type -> BinaryOperator -> JS -> JS+  binaryFunction fnName className classTy op = everywhere (mkT convert)+    where+    convert :: JS -> JS+    convert (JSApp (JSApp (JSApp fn [dict]) [x]) [y]) | isOp fn && isOpDict className classTy dict = JSBinary op x y+    convert other = other+    isOp (JSAccessor fnName' (JSVar "Prelude")) | fnName == fnName' = True+    isOp _ = False+  unary :: String -> String -> Type -> UnaryOperator -> JS -> JS+  unary fnName className classTy op = everywhere (mkT convert)+    where+    convert :: JS -> JS+    convert (JSApp (JSApp fn [dict]) [x]) | isOp fn && isOpDict className classTy dict = JSUnary op x+    convert other = other+    isOp (JSAccessor fnName' (JSVar "Prelude")) | fnName' == fnName = True+    isOp _ = False+  isOpDict className ty (JSAccessor prop (JSVar "Prelude")) | prop == dictName = True+    where+    Right (Ident dictName) = mkDictionaryValueName+      (ModuleName (ProperName "Prelude"))+      (Qualified (Just (ModuleName (ProperName "Prelude"))) (ProperName className))+      ty+  isOpDict _ _ _ = False
src/Language/PureScript/Kinds.hs view
@@ -18,7 +18,7 @@  import Data.Data -import Control.Monad.Unify (TypedUnknown(..))+import Control.Monad.Unify (Unknown)  -- | -- The data type of kinds@@ -27,7 +27,7 @@   -- |   -- Unification variable of type Kind   ---  = KUnknown (TypedUnknown Kind)+  = KUnknown Unknown   -- |   -- The kind of types   --
src/Language/PureScript/Options.hs view
@@ -35,10 +35,14 @@     -- Check the type of Main.main and generate its code     --   , optionsRunMain :: Bool+    -- |+    -- Skip all optimizations+    --+  , optionsNoOptimizations :: Bool   } deriving Show  -- | -- Default compiler options -- defaultOptions :: Options-defaultOptions = Options False False False False+defaultOptions = Options False False False False False
src/Language/PureScript/Parser/Common.hs view
@@ -83,17 +83,10 @@                 , "undefined" ]  -- |--- A list of built-in operator names----builtInOperators :: [String]-builtInOperators = [ "~", "-", "<=", ">=", "<", ">", "*", "/", "%", "++", "+", "<<", ">>>", ">>"-                  , "==", "!=", "&&", "||", "&", "^", "|", "!!", "!" ]---- | -- A list of reserved operators -- reservedOpNames :: [String]-reservedOpNames = builtInOperators ++ [ "=>", "->", "=", ".", "\\" ]+reservedOpNames = [ "=>", "->", "=", ".", "\\" ]  -- | -- Valid first characters for an identifier@@ -257,16 +250,10 @@                   Right <$> P.try (PT.float tokenParser)) P.<?> "number"  -- |--- Parse an operator or a built-in operator----operatorOrBuiltIn :: P.Parsec String u String-operatorOrBuiltIn = P.try operator <|> P.choice (map (\s -> P.try (reservedOp s) >> return s) builtInOperators)---- | -- Parse an identifier or parenthesized operator -- parseIdent :: P.Parsec String ParseState Ident-parseIdent = (Ident <$> identifier) <|> (Op <$> parens operatorOrBuiltIn)+parseIdent = (Ident <$> identifier) <|> (Op <$> parens operator)   -- |@@ -374,7 +361,7 @@ -- Parse an identifier in backticks or an operator -- parseIdentInfix :: P.Parsec String ParseState (Qualified Ident)-parseIdentInfix = (P.between tick tick (parseQualified (Ident <$> identifier))) <|> parseQualified (Op <$> operatorOrBuiltIn)+parseIdentInfix = (P.between tick tick (parseQualified (Ident <$> identifier))) <|> parseQualified (Op <$> operator)  -- | -- Mark the current indentation level
src/Language/PureScript/Parser/JS.hs view
@@ -52,8 +52,8 @@ parseFunction :: P.Parsec String u JS parseFunction = do   C.reserved "function"-  name <- P.optionMaybe (Ident <$> C.identifier)-  args <- P.parens C.tokenParser $ P.commaSep C.tokenParser (Ident <$> C.identifier)+  name <- P.optionMaybe C.identifier+  args <- P.parens C.tokenParser $ P.commaSep C.tokenParser C.identifier   body <- parseJS   return $ JSFunction name args body @@ -61,7 +61,7 @@ parseBlock = JSBlock <$> P.braces C.tokenParser (P.many parseJS)  parseVar :: P.Parsec String u JS-parseVar = JSVar <$> Ident <$> C.identifier+parseVar = JSVar <$> C.identifier  parseJSAtom :: P.Parsec String u JS parseJSAtom = P.choice@@ -74,7 +74,6 @@             , parseBlock             , P.try parseVar             , parseVariableIntroduction-            , P.try parseAssignment             , parseWhile             , parseIf             , parseReturn@@ -110,7 +109,7 @@    $ indexersAndAccessors) P.<?> "javascript"   where   indexersAndAccessors = C.buildPostfixParser postfixTable1 parseJSAtom-  postfixTable1 = [ parseAccessor, parseIndexer, parseConditional ]+  postfixTable1 = [ parseAccessor, parseIndexer, parseConditional, parseAssignment ]   postfixTable2 = [ \v -> P.try $ JSApp v <$> (P.parens C.tokenParser (P.commaSep C.tokenParser parseJS)) ]   operators = [ [ binary    LessThan             "<"     P.AssocLeft]               , [ binary    LessThanOrEqualTo    "<="    P.AssocLeft]@@ -123,7 +122,6 @@               , [ binary    Multiply             "*"     P.AssocLeft]               , [ binary    Divide               "/"     P.AssocLeft]               , [ binary    Modulus              "%"     P.AssocLeft]-              , [ binary    Concat               "+"     P.AssocLeft]               , [ binary    Add                  "+"     P.AssocLeft]               , [ binary    Subtract             "-"     P.AssocLeft]               , [ binary    ShiftLeft            "<<"    P.AssocLeft]@@ -141,7 +139,7 @@ parseVariableIntroduction :: P.Parsec String u JS parseVariableIntroduction = do   C.reserved "var"-  name <- Ident <$> P.identifier C.tokenParser+  name <- P.identifier C.tokenParser   value <- P.optionMaybe $ do     _ <- C.lexeme $ P.char '='     value <- parseJS@@ -149,16 +147,12 @@     return value   return $ JSVariableIntroduction name value -parseAssignment :: P.Parsec String u JS-parseAssignment = do-  tgt <- parseAssignmentTarget+parseAssignment :: JS -> P.Parsec String u JS+parseAssignment tgt = do   _ <- C.lexeme $ P.char '='   value <- parseJS   _ <- C.semi   return $ JSAssignment tgt value--parseAssignmentTarget :: P.Parsec String u JSAssignment-parseAssignmentTarget = C.buildPostfixParser [] (JSAssignVariable <$> Ident <$> P.identifier C.tokenParser)  parseWhile :: P.Parsec String u JS parseWhile = JSWhile <$> (C.reserved "while" *> P.parens C.tokenParser parseJS)
src/Language/PureScript/Parser/Values.hs view
@@ -155,11 +155,7 @@   postfixTable2 = [ \v -> P.try (C.indented *> indexersAndAccessors >>= return . flip App) <*> pure v                   , \v -> flip (TypedValue True) <$> (P.try (C.lexeme (C.indented *> P.string "::")) *> parsePolyType) <*> pure v                   ]-  operators = [ [ Prefix $ C.lexeme (P.try $ C.indented *> C.reservedOp "!") >> return (Unary Not)-                , Prefix $ C.lexeme (P.try $ C.indented *> C.reservedOp "~") >> return (Unary BitwiseNot)-                , Prefix $ C.lexeme (P.try $ C.indented *> C.reservedOp "-") >> return (Unary Negate)-                , Prefix $ C.lexeme (P.try $ C.indented *> C.reservedOp "+") >> return id ]-              , [ Infix (C.lexeme (P.try (C.indented *> C.parseIdentInfix P.<?> "operator") >>= \ident ->+  operators = [ [ Infix (C.lexeme (P.try (C.indented *> C.parseIdentInfix P.<?> "operator") >>= \ident ->                     return (BinaryNoParens ident))) AssocRight ]               ] 
src/Language/PureScript/Pretty/Common.hs view
@@ -13,55 +13,7 @@ -- ----------------------------------------------------------------------------- -{-# LANGUAGE GeneralizedNewtypeDeriving, GADTs #-}- module Language.PureScript.Pretty.Common where--import Data.Char-import Control.Monad.State-import qualified Control.Category as C-import Control.Category ((>>>))-import qualified Control.Arrow as A-import Control.Arrow ((***), (<+>))--import Language.PureScript.Names---- |--- Convert an Ident into a valid Javascript identifier:------  * Alphanumeric characters are kept unmodified------  * Symbols are encoded as a dollar symbol ($) followed by their ordinal value----identToJs :: Ident -> String-identToJs (Ident name) = concatMap identCharToString name-identToJs (Op op) = concatMap identCharToString op-identToJs (Escaped name) = name--identCharToString :: Char -> String-identCharToString c | isAlphaNum c = [c]-identCharToString '_' = "_"-identCharToString '.' = "$dot"-identCharToString '$' = "$dollar"-identCharToString '~' = "$tilde"-identCharToString '=' = "$eq"-identCharToString '<' = "$less"-identCharToString '>' = "$greater"-identCharToString '!' = "$bang"-identCharToString '#' = "$hash"-identCharToString '%' = "$percent"-identCharToString '^' = "$up"-identCharToString '&' = "$amp"-identCharToString '|' = "$bar"-identCharToString '*' = "$times"-identCharToString '/' = "$div"-identCharToString '+' = "$plus"-identCharToString '-' = "$minus"-identCharToString ':' = "$colon"-identCharToString '\\' = "$bslash"-identCharToString '?' = "$qmark"-identCharToString '@' = "$at"-identCharToString c = '$' : show (ord c)  -- | -- Wrap a string in parentheses
src/Language/PureScript/Pretty/JS.hs view
@@ -89,14 +89,14 @@     , currentIndent     , return "}"     ]-  match (JSVar ident) = return (identToJs ident)+  match (JSVar ident) = return ident   match (JSVariableIntroduction ident value) = fmap concat $ sequence     [ return "var "-    , return $ identToJs ident+    , return ident     , maybe (return "") (fmap (" = " ++) . prettyPrintJS') value     ]   match (JSAssignment target value) = fmap concat $ sequence-    [ return $ targetToJs target+    [ prettyPrintJS' target     , return " = "     , prettyPrintJS' value     ]@@ -107,11 +107,11 @@     , prettyPrintJS' sts     ]   match (JSFor ident start end sts) = fmap concat $ sequence-    [ return $ "for (" ++ identToJs ident ++ " = "+    [ return $ "for (" ++ ident ++ " = "     , prettyPrintJS' start-    , return $ "; " ++ identToJs ident ++ " < "+    , return $ "; " ++ ident ++ " < "     , prettyPrintJS' end-    , return $ "; " ++ identToJs ident ++ "++) "+    , return $ "; " ++ ident ++ "++) "     , prettyPrintJS' sts     ]   match (JSIfElse cond thens elses) = fmap concat $ sequence@@ -138,10 +138,6 @@   match (JSRaw js) = return js   match _ = mzero -targetToJs :: JSAssignment -> String-targetToJs (JSAssignVariable ident) = identToJs ident-targetToJs (JSAssignProperty prop target) = targetToJs target ++ "." ++ prop- conditional :: Pattern PrinterState JS ((JS, JS), JS) conditional = mkPattern match   where@@ -160,7 +156,7 @@   match (JSIndexer index val) = (,) <$> prettyPrintJS' index <*> pure val   match _ = mzero -lam :: Pattern PrinterState JS ((Maybe Ident, [Ident]), JS)+lam :: Pattern PrinterState JS ((Maybe String, [String]), JS) lam = mkPattern match   where   match (JSFunction name args ret) = Just ((name, args), ret)@@ -227,8 +223,8 @@                   , [ Wrap indexer $ \index val -> val ++ "[" ++ index ++ "]" ]                   , [ Wrap app $ \args val -> val ++ "(" ++ args ++ ")" ]                   , [ Wrap lam $ \(name, args) ret -> "function "-                        ++ maybe "" identToJs name-                        ++ "(" ++ intercalate ", " (map identToJs args) ++ ") "+                        ++ maybe "" id name+                        ++ "(" ++ (intercalate ", " args) ++ ") "                         ++ ret ]                   , [ Wrap conditional $ \(th, el) cond -> cond ++ " ? " ++ prettyPrintJS1 th ++ " : " ++ prettyPrintJS1 el ]                   , [ binary    LessThan             "<" ]@@ -243,7 +239,6 @@                   , [ binary    Multiply             "*" ]                   , [ binary    Divide               "/" ]                   , [ binary    Modulus              "%" ]-                  , [ binary    Concat               "+" ]                   , [ binary    Add                  "+" ]                   , [ binary    Subtract             "-" ]                   , [ binary    ShiftLeft            "<<" ]
src/Language/PureScript/Pretty/Kinds.hs view
@@ -31,7 +31,7 @@   where   match Star = Just "*"   match Bang = Just "!"-  match (KUnknown (TypedUnknown (Unknown u))) = Just $ 'u' : show u+  match (KUnknown (Unknown u)) = Just $ 'u' : show u   match _ = Nothing  matchRow :: Pattern () Kind ((), Kind)
src/Language/PureScript/Pretty/Types.hs view
@@ -35,7 +35,7 @@   match (TypeVar var) = Just var   match (TypeApp arr ty) | arr == tyArray = Just $ "[" ++ prettyPrintType ty ++ "]"   match (TypeConstructor ctor) = Just $ show ctor-  match (TUnknown (TypedUnknown (Unknown u))) = Just $ 'u' : show u+  match (TUnknown (Unknown u)) = Just $ 'u' : show u   match (Skolem s) = Just $ 's' : show s   match (ConstrainedType deps ty) = Just $ "(" ++ intercalate "," (map (\(pn, ty') -> show pn ++ " (" ++ prettyPrintType ty' ++ ")") deps) ++ ") => " ++ prettyPrintType ty   match (SaturatedTypeSynonym name args) = Just $ show name ++ "<" ++ intercalate "," (map prettyPrintType args) ++ ">"@@ -54,7 +54,7 @@   nameAndTypeToPs name ty = name ++ " :: " ++ prettyPrintType ty   tailToPs :: Type -> String   tailToPs REmpty = ""-  tailToPs (TUnknown (TypedUnknown (Unknown u))) = " | u" ++ show u+  tailToPs (TUnknown (Unknown u)) = " | u" ++ show u   tailToPs (TypeVar var) = " | " ++ var   tailToPs (Skolem s) = " | s" ++ show s   tailToPs _ = error "Invalid row tail"
src/Language/PureScript/Pretty/Values.hs view
@@ -62,12 +62,6 @@   match (Accessor prop val) = Just (prop, val)   match _ = Nothing -indexer :: Pattern () Value (Value, Value)-indexer = mkPattern match-  where-  match (Indexer index val) = Just (index, val)-  match _ = Nothing- objectUpdate :: Pattern () Value ([String], Value) objectUpdate = mkPattern match   where@@ -92,24 +86,6 @@   match (TypedValue _ val ty) = Just (ty, val)   match _ = Nothing -unary :: UnaryOperator -> String -> Operator () Value String-unary op str = Wrap match (++)-  where-  match :: Pattern () Value (String, Value)-  match = mkPattern match'-    where-    match' (Unary op' val) | op' == op = Just (str, val)-    match' _ = Nothing--binary :: BinaryOperator -> String -> Operator () Value String-binary op str = AssocR match (\v1 v2 -> v1 ++ " " ++ str ++ " " ++ v2)-  where-  match :: Pattern () Value (Value, Value)-  match = mkPattern match'-    where-    match' (Binary op' v1 v2) | op' == op = Just (v1, v2)-    match' _ = Nothing- prettyPrintDoNotationElement :: DoNotationElement -> String prettyPrintDoNotationElement (DoNotationValue val) = prettyPrintValue val prettyPrintDoNotationElement (DoNotationBind binder val) = prettyPrintBinder binder ++ " <- " ++ prettyPrintValue val@@ -131,31 +107,6 @@                   , [ Split lam $ \arg val -> "\\" ++ arg ++ " -> " ++ prettyPrintValue val ]                   , [ Wrap ifThenElse $ \(th, el) cond -> cond ++ " ? " ++ prettyPrintValue th ++ " : " ++ prettyPrintValue el ]                   , [ Wrap typed $ \ty val -> val ++ " :: " ++ prettyPrintType ty ]-                  , [ AssocR indexer (\index val -> val ++ " !! " ++ index) ]-                  , [ binary    LessThan             "<" ]-                  , [ binary    LessThanOrEqualTo    "<=" ]-                  , [ binary    GreaterThan          ">" ]-                  , [ binary    GreaterThanOrEqualTo ">=" ]-                  , [ unary     Not                  "!" ]-                  , [ unary     BitwiseNot           "~" ]-                  , [ unary     Negate               "-" ]-                  , [ unary     Positive             "+" ]-                  , [ binary    Multiply             "*" ]-                  , [ binary    Divide               "/" ]-                  , [ binary    Modulus              "%" ]-                  , [ binary    Concat               "++" ]-                  , [ binary    Add                  "+" ]-                  , [ binary    Subtract             "-" ]-                  , [ binary    ShiftLeft            "<<" ]-                  , [ binary    ShiftRight           ">>" ]-                  , [ binary    ZeroFillShiftRight   ">>>" ]-                  , [ binary    EqualTo              "==" ]-                  , [ binary    NotEqualTo           "!=" ]-                  , [ binary    BitwiseAnd           "&" ]-                  , [ binary    BitwiseXor           "^" ]-                  , [ binary    BitwiseOr            "|" ]-                  , [ binary    And                  "&&" ]-                  , [ binary    Or                   "||" ]                   ]  prettyPrintBinderAtom :: Pattern () Binder String
src/Language/PureScript/Scope.hs view
@@ -44,11 +44,11 @@   namesB (VarBinder name) = [name]   namesB _ = []   namesJS :: JS -> [Ident]-  namesJS (JSVar name) = [name]-  namesJS (JSFunction (Just name) args _) = name : args-  namesJS (JSFunction Nothing args _) = args-  namesJS (JSVariableIntroduction name _) = [name]-  namesJS (JSFor name _ _ _) = [name]+  namesJS (JSVar name) = [Ident name]+  namesJS (JSFunction (Just name) args _) = (Ident name) : (Ident `map` args)+  namesJS (JSFunction Nothing args _) = (Ident `map` args)+  namesJS (JSVariableIntroduction name _) = [Ident name]+  namesJS (JSFor name _ _ _) = [Ident name]   namesJS _ = []  -- |
src/Language/PureScript/Sugar/Operators.hs view
@@ -60,7 +60,7 @@   let     applyUserOp name t1 t2 = App (App (Var name) t1) t2     userOps = map (\(name, Fixity a p) -> (name, applyUserOp name, p, a)) . M.toList $ fixities-    sorted = sortBy (compare `on` (\(_, _, p, _) -> p)) (userOps ++ builtIns)+    sorted = sortBy (compare `on` (\(_, _, p, _) -> p)) userOps     groups = groupBy ((==) `on` (\(_, _, p, _) -> p)) sorted   in     map (map (\(name, f, _, a) -> (name, f, a))) groups@@ -110,28 +110,4 @@  globalOp :: String -> Qualified Ident globalOp = Qualified Nothing . Op--builtIns :: [(Qualified Ident, Value -> Value -> Value, Precedence, Associativity)]-builtIns = [ (globalOp "<", Binary LessThan, 3, Infixl)-           , (globalOp "<=", Binary LessThanOrEqualTo, 3, Infixl)-           , (globalOp ">", Binary GreaterThan, 3, Infixl)-           , (globalOp ">=", Binary GreaterThanOrEqualTo, 3, Infixl)-           , (globalOp "!!", flip Indexer, 4, Infixl)-           , (globalOp "*", Binary Multiply, 5, Infixl)-           , (globalOp "/", Binary Divide, 5, Infixl)-           , (globalOp "%", Binary Modulus, 5, Infixl)-           , (globalOp "++", Binary Concat, 6, Infixr)-           , (globalOp "+", Binary Add, 7, Infixl)-           , (globalOp "-", Binary Subtract, 7, Infixl)-           , (globalOp "<<", Binary ShiftLeft, 8, Infixl)-           , (globalOp ">>", Binary ShiftRight, 8, Infixl)-           , (globalOp ">>>", Binary ZeroFillShiftRight, 8, Infixl)-           , (globalOp "==", Binary EqualTo, 9, Infixl)-           , (globalOp "!=", Binary NotEqualTo, 9, Infixl)-           , (globalOp "&", Binary BitwiseAnd, 10, Infixl)-           , (globalOp "^", Binary BitwiseXor, 10, Infixl)-           , (globalOp "|", Binary BitwiseOr, 10, Infixl)-           , (globalOp "&&", Binary And, 11, Infixr)-           , (globalOp "||", Binary Or, 11, Infixr)-           ] 
src/Language/PureScript/Sugar/TypeClasses.hs view
@@ -34,7 +34,7 @@ import Data.Maybe (fromMaybe) import Data.List (nub) import Data.Generics (mkQ, everything)-import Language.PureScript.Pretty.Common (identToJs)+import Language.PureScript.CodeGen.Common (identToJs)  type MemberMap = M.Map (ModuleName, ProperName) (String, [(String, Type)]) @@ -73,7 +73,7 @@ typeClassMemberToDictionaryAccessor :: ProperName -> String -> Declaration -> Declaration typeClassMemberToDictionaryAccessor name arg (TypeDeclaration ident ty) =   ExternDeclaration TypeClassAccessorImport ident-    (Just (JSFunction (Just ident) [Ident "dict"] (JSBlock [JSReturn (JSAccessor (identToJs ident) (JSVar (Ident "dict")))])))+    (Just (JSFunction (Just $ identToJs ident) ["dict"] (JSBlock [JSReturn (JSAccessor (identToJs ident) (JSVar "dict"))])))     (ForAll arg (ConstrainedType [(Qualified Nothing name, TypeVar arg)] ty)) typeClassMemberToDictionaryAccessor _ _ _ = error "Invalid declaration in type class definition" 
src/Language/PureScript/TypeChecker/Kinds.hs view
@@ -38,37 +38,43 @@  import qualified Data.Map as M -instance Unifiable Check Kind where+instance Partial Kind where   unknown = KUnknown   isUnknown (KUnknown u) = Just u   isUnknown _ = Nothing-  KUnknown u1 ?= KUnknown u2 | u1 == u2 = return ()-  KUnknown u ?= k = replace u k-  k ?= KUnknown u = replace u k-  Star ?= Star = return ()-  Bang ?= Bang = return ()-  Row k1 ?= Row k2 = k1 ?= k2-  FunKind k1 k2 ?= FunKind k3 k4 = do-    k1 ?= k3-    k2 ?= k4-  k1 ?= k2 = UnifyT . lift . throwError $ "Cannot unify " ++ prettyPrintKind k1 ++ " with " ++ prettyPrintKind k2 ++ "." +instance Unifiable Check Kind where+  KUnknown u1 =?= KUnknown u2 | u1 == u2 = return ()+  KUnknown u =?= k = u =:= k+  k =?= KUnknown u = u =:= k+  Star =?= Star = return ()+  Bang =?= Bang = return ()+  Row k1 =?= Row k2 = k1 =?= k2+  FunKind k1 k2 =?= FunKind k3 k4 = do+    k1 =?= k3+    k2 =?= k4+  k1 =?= k2 = UnifyT . lift . throwError $ "Cannot unify " ++ prettyPrintKind k1 ++ " with " ++ prettyPrintKind k2 ++ "."+ -- | -- Infer the kind of a single type -- kindOf :: ModuleName -> Type -> Check Kind-kindOf moduleName ty = liftUnify $ starIfUnknown <$> infer ty+kindOf moduleName ty = fmap tidyUp . liftUnify $ starIfUnknown <$> infer ty+  where+  tidyUp (k, sub) = sub $? k  -- | -- Infer the kind of a type constructor with a collection of arguments and a collection of associated data constructors -- kindsOf :: ModuleName -> ProperName -> [String] -> [Type] -> Check Kind-kindsOf moduleName name args ts = fmap starIfUnknown . liftUnify $ do+kindsOf moduleName name args ts = fmap tidyUp . liftUnify $ do   tyCon <- fresh   kargs <- replicateM (length args) fresh   let dict = (name, tyCon) : zip (map ProperName args) kargs   bindLocalTypeVariables moduleName dict $     solveTypes ts kargs tyCon+  where+  tidyUp (k, sub) = sub $? k  -- | -- Simultaneously infer the kinds of several mutually recursive type constructors@@ -93,16 +99,16 @@           solveTypes [ty] kargs synVar) synVars syns       return (syn_ks, data_ks)   where-  tidyUp (ks1, ks2) = (map starIfUnknown ks1, map starIfUnknown ks2)+  tidyUp ((ks1, ks2), sub) = (map (starIfUnknown . (sub $?)) ks1, map (starIfUnknown . (sub $?)) ks2)  -- | -- Solve the set of kind constraints associated with the data constructors for a type constructor ---solveTypes :: [Type] -> [Kind] -> Kind -> UnifyT Check Kind+solveTypes :: [Type] -> [Kind] -> Kind -> UnifyT Kind Check Kind solveTypes ts kargs tyCon = do   ks <- mapM infer ts-  tyCon ?= foldr FunKind Star kargs-  forM_ ks $ \k -> k ?= Star+  tyCon =?= foldr FunKind Star kargs+  forM_ ks $ \k -> k =?= Star   return tyCon  -- |@@ -116,10 +122,10 @@ -- | -- Infer a kind for a type ---infer :: Type -> UnifyT Check Kind+infer :: Type -> UnifyT Kind Check Kind infer (Object row) = do   k <- infer row-  k ?= Row Star+  k =?= Row Star   return Star infer (TypeVar v) = do   Just moduleName <- checkCurrentModule <$> get@@ -134,7 +140,7 @@   k0 <- fresh   k1 <- infer t1   k2 <- infer t2-  k1 ?= FunKind k2 k0+  k1 =?= FunKind k2 k0   return k0 infer (ForAll ident ty) = do   k <- fresh@@ -146,11 +152,11 @@ infer (RCons _ ty row) = do   k1 <- infer ty   k2 <- infer row-  k2 ?= Row k1+  k2 =?= Row k1   return $ Row k1 infer (ConstrainedType deps ty) = do   mapM_ (infer . snd) deps   k <- infer ty-  k ?= Star+  k =?= Star   return Star infer _ = error "Invalid argument to infer"
src/Language/PureScript/TypeChecker/Monad.hs view
@@ -210,7 +210,7 @@ canonicalizeType mn env (Qualified Nothing nm) = case (mn, nm) `M.lookup` types env of   Just (_, DataAlias mn' pn') -> (mn', pn')   _ -> (mn, nm)-  + -- | -- Canonicalize a data constructor by resolving any aliases introduced by module imports --@@ -299,13 +299,13 @@ -- | -- Lift a computation in the @Check@ monad into the substitution monad. ---liftCheck :: Check a -> UnifyT Check a+liftCheck :: Check a -> UnifyT t Check a liftCheck = UnifyT . lift . lift  -- | -- Run a computation in the substitution monad, generating a return value and the final substitution. ---liftUnify :: (Data a) => UnifyT Check a -> Check a+liftUnify :: (Partial t) => UnifyT t Check a -> Check (a, Substitution t) liftUnify unify = do   st <- get   e <- runUnify (defaultUnifyState { unifyNextVar = checkNextVar st }) unify@@ -313,7 +313,7 @@     Left err -> throwError err     Right (a, ust) -> do       modify $ \st -> st { checkNextVar = unifyNextVar ust }-      return $ runSubstitution (unifyCurrentSubstitution ust) a+      return (a, unifyCurrentSubstitution ust)  -- | -- Replace any unqualified names in a type wit their qualified versionss
src/Language/PureScript/TypeChecker/Types.hs view
@@ -67,22 +67,24 @@ import qualified Data.Map as M import Data.Function (on) -instance Unifiable Check Type where+instance Partial Type where   unknown = TUnknown   isUnknown (TUnknown u) = Just u   isUnknown _ = Nothing-  (?=) = unifyTypes +instance Unifiable Check Type where+  (=?=) = unifyTypes+ -- | -- Unify two types, updating the current substitution ---unifyTypes :: Type -> Type -> UnifyT Check ()+unifyTypes :: Type -> Type -> UnifyT Type Check () unifyTypes t1 t2 = rethrow (\e -> "Error unifying type " ++ prettyPrintType t1 ++ " with type " ++ prettyPrintType t2 ++ ":\n" ++ e) $ do   unifyTypes' t1 t2   where   unifyTypes' (TUnknown u1) (TUnknown u2) | u1 == u2 = return ()-  unifyTypes' (TUnknown u) t = replace u t-  unifyTypes' t (TUnknown u) = replace u t+  unifyTypes' (TUnknown u) t = u =:= t+  unifyTypes' t (TUnknown u) = u =:= t   unifyTypes' (SaturatedTypeSynonym name args) ty = do     ty1 <- expandTypeSynonym name args     ty1 `unifyTypes` ty@@ -95,7 +97,7 @@     sk <- skolemize ident ty1     sk `unifyTypes` ty2   unifyTypes' ty f@(ForAll _ _) = f `unifyTypes` ty-  unifyTypes' (Object row1) (Object row2) = row1 ?= row2+  unifyTypes' (Object row1) (Object row2) = row1 =?= row2   unifyTypes' (TypeVar v1) (TypeVar v2) | v1 == v2 = return ()   unifyTypes' (TypeConstructor c1) (TypeConstructor c2) = do     env <- getEnv@@ -118,7 +120,7 @@ -- trailing row unification variable, if appropriate, otherwise leftover labels result in a unification -- error. ---unifyRows :: Type -> Type -> UnifyT Check ()+unifyRows :: Type -> Type -> UnifyT Type Check () unifyRows r1 r2 =   let     (s1, r1') = rowToList r1@@ -127,17 +129,17 @@     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 (?=))+    forM_ int (uncurry (=?=))     unifyRows' sd1 r1' sd2 r2'   where-  unifyRows' :: [(String, Type)] -> Type -> [(String, Type)] -> Type -> UnifyT Check ()-  unifyRows' [] (TUnknown u) sd r = replace u (rowFromList (sd, r))-  unifyRows' sd r [] (TUnknown u) = replace u (rowFromList (sd, r))+  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' ((name, ty):row) r others u@(TUnknown un) = do     occursCheck un ty     forM_ row $ \(_, t) -> occursCheck un t     u' <- fresh-    u ?= RCons name ty u'+    u =?= RCons name ty u'     unifyRows' row r others u'   unifyRows' [] REmpty [] REmpty = return ()   unifyRows' [] (TypeVar v1) [] (TypeVar v2) | v1 == v2 = return ()@@ -156,7 +158,7 @@ -- typesOf :: ModuleName -> [(Ident, Value)] -> Check [(Ident, (Value, Type))] typesOf moduleName vals = do-  tys <- liftUnify $ do+  tys <- fmap tidyUp . liftUnify $ do     let es = map isTyped vals         typed = filter (isJust . snd . snd) es         untyped = filter (isNothing . snd . snd) es@@ -174,11 +176,11 @@           return (ident, (val', ty'))         (ident, (val, Nothing)) -> do           TypedValue _ val' ty <- bindNames dict $ infer val-          ty ?= fromMaybe (error "name not found in dictionary") (lookup ident untypedDict)+          ty =?= fromMaybe (error "name not found in dictionary") (lookup ident untypedDict)           return (ident, (val', ty))       when (moduleName == ModuleName (ProperName "Main") && fst e == Ident "main") $ do         [eff, a] <- replicateM 2 fresh-        ty ?= TypeApp (TypeApp (TypeConstructor (Qualified (Just (ModuleName (ProperName "Eff"))) (ProperName "Eff"))) eff) a+        ty =?= TypeApp (TypeApp (TypeConstructor (Qualified (Just (ModuleName (ProperName "Eff"))) (ProperName "Eff"))) eff) a       escapeCheck val ty       return triple   forM_ tys $ skolemEscapeCheck . snd . snd@@ -186,6 +188,8 @@     val' <- replaceTypeClassDictionaries moduleName val     return (ident, (overTypes (desaturateAllTypeSynonyms . setifyAll) $ val'                    , varIfUnknown . desaturateAllTypeSynonyms . setifyAll $ ty))+  where+  tidyUp (ts, sub) = map (\(i, (val, ty)) -> (i, (overTypes (sub $?) val, sub $? ty))) ts  -- | -- Check if a value contains a type annotation@@ -257,14 +261,14 @@ -- | -- Ensure unsolved unification variables do not escape ---escapeCheck :: Value -> Type -> UnifyT Check ()+escapeCheck :: Value -> Type -> UnifyT Type Check () escapeCheck value ty = do   subst <- unifyCurrentSubstitution <$> UnifyT get-  let visibleUnknowns = nub $ unknowns $ runSubstitution subst ty+  let visibleUnknowns = nub $ unknowns $ subst $? ty   let allUnknowns = findAllTypes value   forM_ allUnknowns $ \t -> do-    let unsolvedUnknowns = nub . unknowns $ runSubstitution subst t-    guardWith ("Escape check fails" ++ show ( runSubstitution subst ty, runSubstitution subst t)) $ null $ unsolvedUnknowns \\ visibleUnknowns+    let unsolvedUnknowns = nub . unknowns $ subst $? t+    guardWith ("Escape check fails" ++ show (subst $? ty, subst $? t)) $ null $ unsolvedUnknowns \\ visibleUnknowns  -- | -- Find all type annotations occuring inside a value@@ -308,7 +312,7 @@       toName = (:) 't' . show       ty' = everywhere (mkT typeToVar) $ ty       typeToVar :: Type -> Type-      typeToVar (TUnknown (TypedUnknown (Unknown u))) = TypeVar (toName u)+      typeToVar (TUnknown (Unknown u)) = TypeVar (toName u)       typeToVar t = t   in mkForAll (sort . map (toName . runUnknown) $ unks) ty' @@ -321,14 +325,14 @@ -- | -- Replace named type variables with new unification variables ---replaceAllVarsWithUnknowns :: Type -> UnifyT Check Type+replaceAllVarsWithUnknowns :: Type -> UnifyT Type Check Type replaceAllVarsWithUnknowns (ForAll ident ty) = replaceVarWithUnknown ident ty >>= replaceAllVarsWithUnknowns replaceAllVarsWithUnknowns ty = return ty  -- | -- Replace a single type variable with a new unification variable ---replaceVarWithUnknown :: String -> Type -> UnifyT Check Type+replaceVarWithUnknown :: String -> Type -> UnifyT Type Check Type replaceVarWithUnknown ident ty = do   tu <- fresh   return $ replaceTypeVars ident tu $ ty@@ -356,7 +360,7 @@ -- | -- Replace a type synonym and its arguments with the aliased type ---expandTypeSynonym :: Qualified ProperName -> [Type] -> UnifyT Check Type+expandTypeSynonym :: Qualified ProperName -> [Type] -> UnifyT Type Check Type expandTypeSynonym name args = do   env <- getEnv   Just moduleName <- checkCurrentModule <$> get@@ -373,28 +377,21 @@ -- | -- Infer a type for a value, rethrowing any error to provide a more useful error message ---infer :: Value -> UnifyT Check Value+infer :: Value -> UnifyT Type Check Value infer val = rethrow (\e -> "Error inferring type of term " ++ prettyPrintValue val ++ ":\n" ++ e) $ infer' val  -- | -- Infer a type for a value ---infer' :: Value -> UnifyT Check Value+infer' :: Value -> UnifyT Type Check Value infer' v@(NumericLiteral _) = return $ TypedValue True v tyNumber infer' v@(StringLiteral _) = return $ TypedValue True v tyString infer' v@(BooleanLiteral _) = return $ TypedValue True v tyBoolean infer' (ArrayLiteral vals) = do   ts <- mapM infer vals   els <- fresh-  forM_ ts $ \(TypedValue _ _ t) -> els ?= TypeApp tyArray t+  forM_ ts $ \(TypedValue _ _ t) -> els =?= TypeApp tyArray t   return $ TypedValue True (ArrayLiteral ts) els-infer' (Unary op val) = do-  v <- infer val-  inferUnary op v-infer' (Binary op left right) = do-  v1 <- infer left-  v2 <- infer right-  inferBinary op v1 v2 infer' (ObjectLiteral ps) = do   ensureNoDuplicateProperties ps   ts <- mapM (infer . snd) ps@@ -409,11 +406,6 @@   oldTys <- zip (map fst ps) <$> replicateM (length ps) fresh   o' <- check o $ Object $ rowFromList (oldTys, row)   return $ TypedValue True (ObjectUpdate o' newVals) $ Object $ rowFromList (newTys, row)-infer' (Indexer index val) = do-  el <- fresh-  index' <- check index tyNumber-  val' <- check val (TypeApp tyArray el)-  return $ TypedValue True (Indexer (TypedValue True index' tyNumber) (TypedValue True val' (TypeApp tyArray el))) el infer' (Accessor prop val) = do   typed@(TypedValue _ _ objTy) <- infer val   propTy <- inferProperty objTy prop@@ -466,7 +458,7 @@   cond' <- check cond tyBoolean   v2@(TypedValue _ _ t2) <- infer th   v3@(TypedValue _ _ t3) <- infer el-  t2 ?= t3+  t2 =?= t3   return $ TypedValue True (IfThenElse cond' v2 v3) t2 infer' (TypedValue checkType val ty) = do   Just moduleName <- checkCurrentModule <$> get@@ -480,7 +472,7 @@ -- | -- Infer the type of a property inside a record with a given type ---inferProperty :: Type -> String -> UnifyT Check (Maybe Type)+inferProperty :: Type -> String -> UnifyT Type Check (Maybe Type) inferProperty (Object row) prop = do   let (props, _) = rowToList row   return $ lookup prop props@@ -493,109 +485,13 @@ inferProperty _ _ = return Nothing  -- |--- Infer the type of a unary operator application----inferUnary :: UnaryOperator -> Value -> UnifyT Check Value-inferUnary op (TypedValue _ val valTy) =-  case fromMaybe (error "Invalid operator") $ lookup op unaryOps of-    (valTy', resTy) -> do-      valTy' ?= valTy-      return $ TypedValue True (Unary op val) resTy-inferUnary _ _ = error "Invalid arguments to inferUnary"---- |--- Check the type of a unary operator application----checkUnary :: UnaryOperator -> Value -> Type -> UnifyT Check Value-checkUnary op val res =-  case fromMaybe (error "Invalid operator") $ lookup op unaryOps of-    (valTy, resTy) -> do-      res ?= resTy-      val' <- check val valTy-      return $ Unary op val'---- |--- Built-in unary operators----unaryOps :: [(UnaryOperator, (Type, Type))]-unaryOps = [ (Negate, (tyNumber, tyNumber))-           , (Not, (tyBoolean, tyBoolean))-           , (BitwiseNot, (tyNumber, tyNumber))-           ]---- |--- Infer the type of a binary operator application----inferBinary :: BinaryOperator -> Value -> Value -> UnifyT Check Value-inferBinary op left@(TypedValue _ _ leftTy) right@(TypedValue _ _ rightTy) | isEqualityTest op = do-  leftTy ?= rightTy-  return $ TypedValue True (Binary op left right) tyBoolean-inferBinary op left@(TypedValue _ _ leftTy) right@(TypedValue _ _ rightTy) =-  case fromMaybe (error "Invalid operator") $ lookup op binaryOps of-    (valTy, resTy) -> do-      leftTy ?= valTy-      rightTy ?= valTy-      return $ TypedValue True (Binary op left right) resTy-inferBinary _ _ _ = error "Invalid arguments to inferBinary"---- |--- Check the type of a binary operator application----checkBinary :: BinaryOperator -> Value -> Value -> Type -> UnifyT Check Value-checkBinary op left right res | isEqualityTest op = do-  res ?= tyBoolean-  left'@(TypedValue _ _ t1) <- infer left-  right'@(TypedValue _ _ t2) <- infer right-  t1 ?= t2-  return $ Binary op left' right'-checkBinary op left right res =-  case fromMaybe (error "Invalid operator") $ lookup op binaryOps of-    (valTy, resTy) -> do-      res ?= resTy-      left' <- check left valTy-      right' <- check right valTy-      return $ Binary op left' right'---- |--- Check if a @BinaryOperator@ is an equality test----isEqualityTest :: BinaryOperator -> Bool-isEqualityTest EqualTo = True-isEqualityTest NotEqualTo = True-isEqualityTest _ = False---- |--- Built-in binary operators----binaryOps :: [(BinaryOperator, (Type, Type))]-binaryOps = [ (Add, (tyNumber, tyNumber))-            , (Subtract, (tyNumber, tyNumber))-            , (Multiply, (tyNumber, tyNumber))-            , (Divide, (tyNumber, tyNumber))-            , (Modulus, (tyNumber, tyNumber))-            , (BitwiseAnd, (tyNumber, tyNumber))-            , (BitwiseOr, (tyNumber, tyNumber))-            , (BitwiseXor, (tyNumber, tyNumber))-            , (ShiftRight, (tyNumber, tyNumber))-            , (ZeroFillShiftRight, (tyNumber, tyNumber))-            , (And, (tyBoolean, tyBoolean))-            , (Or, (tyBoolean, tyBoolean))-            , (Concat, (tyString, tyString))-            , (Modulus, (tyNumber, tyNumber))-            , (LessThan, (tyNumber, tyBoolean))-            , (LessThanOrEqualTo, (tyNumber, tyBoolean))-            , (GreaterThan, (tyNumber, tyBoolean))-            , (GreaterThanOrEqualTo, (tyNumber, tyBoolean))-            ]---- | -- Infer the types of variables brought into scope by a binder ---inferBinder :: Type -> Binder -> UnifyT Check (M.Map Ident Type)+inferBinder :: Type -> Binder -> UnifyT Type Check (M.Map Ident Type) inferBinder _ NullBinder = return M.empty-inferBinder val (StringBinder _) = val ?= tyString >> return M.empty-inferBinder val (NumberBinder _) = val ?= tyNumber >> return M.empty-inferBinder val (BooleanBinder _) = val ?= tyBoolean >> return M.empty+inferBinder val (StringBinder _) = val =?= tyString >> return M.empty+inferBinder val (NumberBinder _) = val =?= tyNumber >> return M.empty+inferBinder val (BooleanBinder _) = val =?= tyBoolean >> return M.empty inferBinder val (VarBinder name) = return $ M.singleton name val inferBinder val (NullaryBinder ctor) = do   env <- getEnv@@ -621,11 +517,11 @@   row <- fresh   rest <- fresh   m1 <- inferRowProperties row rest props-  val ?= Object row+  val =?= Object row   return m1   where-  inferRowProperties :: Type -> Type -> [(String, Binder)] -> UnifyT Check (M.Map Ident Type)-  inferRowProperties nrow row [] = nrow ?= row >> return M.empty+  inferRowProperties :: Type -> Type -> [(String, Binder)] -> UnifyT Type Check (M.Map Ident Type)+  inferRowProperties nrow row [] = nrow =?= row >> return M.empty   inferRowProperties nrow row ((name, binder):binders) = do     propTy <- fresh     m1 <- inferBinder propTy binder@@ -634,13 +530,13 @@ inferBinder val (ArrayBinder binders) = do   el <- fresh   m1 <- M.unions <$> mapM (inferBinder el) binders-  val ?= TypeApp tyArray el+  val =?= TypeApp tyArray el   return m1 inferBinder val (ConsBinder headBinder tailBinder) = do   el <- fresh   m1 <- inferBinder el headBinder   m2 <- inferBinder val tailBinder-  val ?= TypeApp tyArray el+  val =?= TypeApp tyArray el   return $ m1 `M.union` m2 inferBinder val (NamedBinder name binder) = do   m <- inferBinder val binder@@ -649,7 +545,7 @@ -- | -- Check the types of the return values in a set of binders in a case statement ---checkBinders :: [Type] -> Type -> [([Binder], Maybe Guard, Value)] -> UnifyT Check [([Binder], Maybe Guard, Value)]+checkBinders :: [Type] -> Type -> [([Binder], Maybe Guard, Value)] -> UnifyT Type Check [([Binder], Maybe Guard, Value)] checkBinders _ _ [] = return [] checkBinders nvals ret ((binders, grd, val):bs) = do   Just moduleName <- checkCurrentModule <$> get@@ -667,7 +563,7 @@ -- | -- Check that a local variable name is not already used ---assignVariable :: Ident -> UnifyT Check ()+assignVariable :: Ident -> UnifyT Type Check () assignVariable name = do   env <- checkEnv <$> get   Just moduleName <- checkCurrentModule <$> get@@ -679,7 +575,7 @@ -- Check the type of the return values of a statement, returning whether or not the statement returns on -- all code paths ---checkStatement :: M.Map Ident Type -> Type -> Statement -> UnifyT Check (Bool, M.Map Ident Type, Statement)+checkStatement :: M.Map Ident Type -> Type -> Statement -> UnifyT Type Check (Bool, M.Map Ident Type, Statement) checkStatement mass _ (VariableIntroduction name val) = do   assignVariable name   val'@(TypedValue _ _ t) <- infer val@@ -688,7 +584,7 @@   val'@(TypedValue _ _ t) <- infer val   case M.lookup ident mass of     Nothing -> throwError $ "No local variable with name " ++ show ident-    Just ty -> do t ?= ty+    Just ty -> do t =?= ty                   return (False, mass, Assignment ident val') checkStatement mass ret (While val inner) = do   val' <- check val tyBoolean@@ -711,7 +607,7 @@ -- | -- Check the type of an if-then-else statement ---checkIfStatement :: M.Map Ident Type -> Type -> IfStatement -> UnifyT Check (Bool, IfStatement)+checkIfStatement :: M.Map Ident Type -> Type -> IfStatement -> UnifyT Type Check (Bool, IfStatement) checkIfStatement mass ret (IfStatement val thens Nothing) = do   val' <- check val tyBoolean   (_, _, thens') <- checkBlock mass ret thens@@ -725,7 +621,7 @@ -- | -- Check the type of an else statement ---checkElseStatement :: M.Map Ident Type -> Type -> ElseStatement -> UnifyT Check (Bool, ElseStatement)+checkElseStatement :: M.Map Ident Type -> Type -> ElseStatement -> UnifyT Type Check (Bool, ElseStatement) checkElseStatement mass ret (Else elses) = do   (allCodePathsReturn, _, elses') <- checkBlock mass ret elses   return (allCodePathsReturn, Else elses')@@ -734,7 +630,7 @@ -- | -- Check the type of the return value of a block of statements ---checkBlock :: M.Map Ident Type -> Type -> [Statement] -> UnifyT Check (Bool, M.Map Ident Type, [Statement])+checkBlock :: M.Map Ident Type -> Type -> [Statement] -> UnifyT Type Check (Bool, M.Map Ident Type, [Statement]) checkBlock mass _ [] = return (False, mass, []) checkBlock mass ret (s:ss) = do   Just moduleName <- checkCurrentModule <$> get@@ -749,7 +645,7 @@ -- | -- Skolemize a type variable by replacing its instances with fresh skolem constants ---skolemize :: String -> Type -> UnifyT Check Type+skolemize :: String -> Type -> UnifyT Type Check Type skolemize ident ty = do   tsk <- Skolem . runUnknown <$> fresh'   return $ replaceTypeVars ident tsk ty@@ -757,7 +653,7 @@ -- | -- Check the type of a value, rethrowing errors to provide a better error message ---check :: Value -> Type -> UnifyT Check Value+check :: Value -> Type -> UnifyT Type Check Value check val ty = rethrow errorMessage $ check' val ty   where   errorMessage msg =@@ -771,7 +667,7 @@ -- | -- Check the type of a value ---check' :: Value -> Type -> UnifyT Check Value+check' :: Value -> Type -> UnifyT Type Check Value check' val (ForAll idents ty) = do   sk <- skolemize idents ty   check val sk@@ -790,18 +686,12 @@   val'@(TypedValue _ _ ty) <- infer val   -- Don't unify an unknown with an inferred polytype   ty' <- replaceAllVarsWithUnknowns ty-  ty' ?= u+  ty' =?= u   return val' check' v@(NumericLiteral _) t | t == tyNumber = return v check' v@(StringLiteral _) t | t == tyString = return v check' v@(BooleanLiteral _) t | t == tyBoolean = return v-check' (Unary op val) ty = checkUnary op val ty-check' (Binary op left right) ty = checkBinary op left right ty check' (ArrayLiteral vals) (TypeApp a ty) | a == tyArray = ArrayLiteral <$> forM vals (\val -> check val ty)-check' (Indexer index vals) ty = do-  index' <- check index tyNumber-  vals' <- check vals (TypeApp tyArray ty)-  return $ Indexer index' vals' check' (Abs arg ret) (TypeApp (TypeApp t argTy) retTy) | t == tyFunction = do   Just moduleName <- checkCurrentModule <$> get   ret' <- bindLocalVariables moduleName [(arg, argTy)] $ check ret retTy@@ -814,7 +704,8 @@   Just moduleName <- checkCurrentModule <$> get   ty1 <- lookupVariable moduleName var   repl <- replaceAllTypeSynonyms ty1-  v' <- subsumes (Just v) repl ty+  ty' <- replaceAllTypeSynonyms ty+  v' <- subsumes (Just v) repl ty'   case v' of     Nothing -> throwError "Unable to check type subsumption"     Just v'' -> return v''@@ -878,10 +769,10 @@ -- -- The @lax@ parameter controls whether or not every record member has to be provided. For object updates, this is not the case. ---checkProperties :: [(String, Value)] -> Type -> Bool -> UnifyT Check [(String, Value)]+checkProperties :: [(String, Value)] -> Type -> Bool -> UnifyT Type Check [(String, Value)] checkProperties ps row lax = let (ts, r') = rowToList row in go ps ts r' where   go [] [] REmpty = return []-  go [] [] u@(TUnknown _) = do u ?= REmpty+  go [] [] u@(TUnknown _) = do u =?= REmpty                                return []   go [] [] (Skolem _) | lax = return []   go [] ((p, _): _) _ | lax = return []@@ -890,7 +781,7 @@   go ((p,v):ps') [] u@(TUnknown _) = do     v'@(TypedValue _ _ ty) <- infer v     rest <- fresh-    u ?= RCons p ty rest+    u =?= RCons p ty rest     ps'' <- go ps' [] rest     return $ (p, v') : ps''   go ((p,v):ps') ts r =@@ -898,7 +789,7 @@       Nothing -> do         v'@(TypedValue _ _ ty) <- infer v         rest <- fresh-        r ?= RCons p ty rest+        r =?= RCons p ty rest         ps'' <- go ps' ts rest         return $ (p, v') : ps''       Just ty -> do@@ -910,7 +801,7 @@ -- | -- Check the type of a function application, rethrowing errors to provide a better error message ---checkFunctionApplication :: Value -> Type -> Value -> Type -> UnifyT Check Value+checkFunctionApplication :: Value -> Type -> Value -> Type -> UnifyT Type Check Value checkFunctionApplication fn fnTy arg ret = rethrow errorMessage $ checkFunctionApplication' fn fnTy arg ret   where   errorMessage msg = "Error applying function of type "@@ -921,9 +812,9 @@ -- | -- Check the type of a function application ---checkFunctionApplication' :: Value -> Type -> Value -> Type -> UnifyT Check Value+checkFunctionApplication' :: Value -> Type -> Value -> Type -> UnifyT Type Check Value checkFunctionApplication' fn (TypeApp (TypeApp tyFunction' argTy) retTy) arg ret = do-  tyFunction' ?= tyFunction+  tyFunction' =?= tyFunction   arg' <- check arg argTy   _ <- subsumes Nothing retTy ret   return $ App fn arg'@@ -935,7 +826,7 @@     TypedValue _ v t <- infer arg     TypedValue True v <$> replaceAllVarsWithUnknowns t   let ty = (\(TypedValue _ _ t) -> t) arg'-  u ?= function ty ret+  u =?= function ty ret   return $ App fn arg' checkFunctionApplication' fn (SaturatedTypeSynonym name tyArgs) arg ret = do   ty <- expandTypeSynonym name tyArgs@@ -953,7 +844,7 @@ -- | -- Check whether one type subsumes another, rethrowing errors to provide a better error message ---subsumes :: Maybe Value -> Type -> Type -> UnifyT Check (Maybe Value)+subsumes :: Maybe Value -> Type -> Type -> UnifyT Type Check (Maybe Value) subsumes val ty1 ty2 = rethrow errorMessage $ subsumes' val ty1 ty2   where   errorMessage msg = "Error checking that type "@@ -965,7 +856,7 @@ -- | -- Check whether one type subsumes another ---subsumes' :: Maybe Value -> Type -> Type -> UnifyT Check (Maybe Value)+subsumes' :: Maybe Value -> Type -> Type -> UnifyT Type Check (Maybe Value) subsumes' val (ForAll ident ty1) ty2 = do   replaced <- replaceVarWithUnknown ident ty1   subsumes val replaced ty2@@ -973,6 +864,12 @@   subsumes Nothing arg2 arg1   subsumes Nothing ret1 ret2   return val+subsumes' val (SaturatedTypeSynonym name tyArgs) ty2 = do+  ty1 <- expandTypeSynonym name tyArgs+  subsumes val ty1 ty2+subsumes' val ty1 (SaturatedTypeSynonym name tyArgs) = do+  ty2 <- expandTypeSynonym name tyArgs+  subsumes val ty1 ty2 subsumes' (Just val) (ConstrainedType constraints ty1) ty2 = do   env <- getEnv   dicts <- getTypeClassDictionaries@@ -980,6 +877,6 @@   _ <- subsumes' Nothing ty1 ty2   return . Just $ foldl App val (map (flip TypeClassDictionary dicts) (qualifyAllUnqualifiedNames moduleName env constraints)) subsumes' val ty1 ty2 = do-  ty1 ?= ty2+  ty1 =?= ty2   return val 
src/Language/PureScript/Types.hs view
@@ -31,7 +31,7 @@   -- |   -- A unification variable of type Type   ---  = TUnknown (TypedUnknown Type)+  = TUnknown Unknown   -- |   -- Javascript numbers   --
src/Language/PureScript/Values.hs view
@@ -28,112 +28,6 @@ type Guard = Value  -- |--- Built-in unary operators----data UnaryOperator-  -- |-  -- Numeric negation-  ---  = Negate-  -- |-  -- Boolean negation-  ---  | Not-  -- |-  -- Bitwise negation-  ---  | BitwiseNot-  -- |-  -- Numeric unary \'plus\'-  ---  | Positive deriving (Show, Eq, Data, Typeable)---- |--- Built-in binary operators----data BinaryOperator-  -- |-  -- Numeric addition-  ---  = Add-  -- |-  -- Numeric subtraction-  ---  | Subtract-  -- |-  -- Numeric multiplication-  ---  | Multiply-  -- |-  -- Numeric division-  ---  | Divide-  -- |-  -- Remainder-  ---  | Modulus-  -- |-  -- Generic equality test-  ---  | EqualTo-  -- |-  -- Generic inequality test-  ---  | NotEqualTo-  -- |-  -- Numeric less-than-  ---  | LessThan-  -- |-  -- Numeric less-than-or-equal-  ---  | LessThanOrEqualTo-  -- |-  -- Numeric greater-than-  ---  | GreaterThan-  -- |-  -- Numeric greater-than-or-equal-  ---  | GreaterThanOrEqualTo-  -- |-  -- Boolean and-  ---  | And-  -- |-  -- Boolean or-  ---  | Or-  -- |-  -- Bitwise and-  ---  | BitwiseAnd-  -- |-  -- Bitwise or-  ---  | BitwiseOr-  -- |-  -- Bitwise xor-  ---  | BitwiseXor-  -- |-  -- Bitwise left shift-  ---  | ShiftLeft-  -- |-  -- Bitwise right shift-  ---  | ShiftRight-  -- |-  -- Bitwise right shift with zero-fill-  ---  | ZeroFillShiftRight-  -- |-  -- String concatenation-  ---  | Concat deriving (Show, Eq, Data, Typeable)---- | -- Data type for values -- data Value@@ -150,14 +44,6 @@   --   | BooleanLiteral Bool   -- |-  -- Unary operator application-  ---  | Unary UnaryOperator Value-  -- |-  -- Binary operator application-  ---  | Binary BinaryOperator Value Value-  -- |   -- Binary operator application. During the rebracketing phase of desugaring, this data constructor   -- will be removed.   --@@ -171,10 +57,6 @@   -- An array literal   --   | ArrayLiteral [Value]-  -- |-  -- An array indexing expression-  ---  | Indexer Value Value   -- |   -- An object literal   --
tests/Main.hs view
@@ -66,7 +66,7 @@ assertCompiles inputFile = do   putStrLn $ "assert " ++ inputFile ++ " compiles successfully"   prelude <- preludeFilename-  assert (P.defaultOptions { P.optionsRunMain = True }) [prelude, inputFile] $ either (return . Just) $ \js -> do+  assert (P.defaultOptions { P.optionsRunMain = True, P.optionsNoOptimizations = True }) [prelude, inputFile] $ either (return . Just) $ \js -> do     args <- getArgs     if "--run-js" `elem` args     then do