packages feed

purescript 0.4.2 → 0.4.2.1

raw patch · 38 files changed

+816/−552 lines, 38 files

Files

docgen/Main.hs view
@@ -60,7 +60,7 @@  renderModule :: P.Module -> Docs renderModule (P.Module moduleName ds) = do-  headerLevel 2 $ "Module " ++ (P.runModuleName moduleName)+  headerLevel 2 $ "Module " ++ P.runModuleName moduleName   spacer   headerLevel 3 "Types"   spacer@@ -90,23 +90,23 @@ renderDeclaration n (P.ExternDeclaration _ ident _ ty) =   atIndent n $ show ident ++ " :: " ++ P.prettyPrintType ty renderDeclaration n (P.DataDeclaration name args ctors) = do-  let typeName = P.runProperName name ++ " " ++ intercalate " " args+  let typeName = P.runProperName name ++ " " ++ unwords args   atIndent n $ "data " ++ typeName ++ " where"-  forM_ ctors $ \(ctor, tys) -> do-    atIndent (n + 2) $ P.runProperName ctor ++ " :: " ++ concat (map (\ty -> P.prettyPrintType ty ++ " -> ") tys) ++ typeName+  forM_ ctors $ \(ctor, tys) ->+    atIndent (n + 2) $ P.runProperName ctor ++ " :: " ++ concatMap (\ty -> P.prettyPrintType ty ++ " -> ") tys ++ typeName renderDeclaration n (P.ExternDataDeclaration name kind) =   atIndent n $ "data " ++ P.runProperName name ++ " :: " ++ P.prettyPrintKind kind renderDeclaration n (P.TypeSynonymDeclaration name args ty) = do-  let typeName = P.runProperName name ++ " " ++ intercalate " " args+  let typeName = P.runProperName name ++ " " ++ unwords args   atIndent n $ "type " ++ typeName ++ " = " ++ P.prettyPrintType ty-renderDeclaration n (P.TypeClassDeclaration name arg ds) = do-  atIndent n $ "class " ++ P.runProperName name ++ " " ++ arg ++ " where"+renderDeclaration n (P.TypeClassDeclaration name args ds) = do+  atIndent n $ "class " ++ P.runProperName name ++ " " ++ unwords args ++ " where"   mapM_ (renderDeclaration (n + 2)) ds-renderDeclaration n (P.TypeInstanceDeclaration constraints name ty _) = do+renderDeclaration n (P.TypeInstanceDeclaration constraints name tys _) = do   let constraintsText = case constraints of                           [] -> ""-                          cs -> "(" ++ intercalate "," (map (\(pn, ty') -> show pn ++ " (" ++ P.prettyPrintType ty' ++ ")") cs) ++ ") => "-  atIndent n $ constraintsText ++ "instance " ++ show name ++ " " ++ P.prettyPrintType ty+                          cs -> "(" ++ intercalate "," (map (\(pn, tys') -> show pn ++ " (" ++ unwords (map (("(" ++) . (++ ")") . P.prettyPrintType) tys') ++ ")") cs) ++ ") => "+  atIndent n $ constraintsText ++ "instance " ++ show name ++ " " ++ unwords (map (("(" ++) . (++ ")") . P.prettyPrintType) tys) renderDeclaration _ _ = return ()  getName :: P.Declaration -> String@@ -120,22 +120,22 @@ getName _ = error "Invalid argument to getName"  isValueDeclaration :: P.Declaration -> Bool-isValueDeclaration (P.TypeDeclaration _ _) = True-isValueDeclaration (P.ExternDeclaration _ _ _ _) = True+isValueDeclaration P.TypeDeclaration{} = True+isValueDeclaration P.ExternDeclaration{} = True isValueDeclaration _ = False  isTypeDeclaration :: P.Declaration -> Bool-isTypeDeclaration (P.DataDeclaration _ _ _) = True-isTypeDeclaration (P.ExternDataDeclaration _ _) = True-isTypeDeclaration (P.TypeSynonymDeclaration _ _ _) = True+isTypeDeclaration P.DataDeclaration{} = True+isTypeDeclaration P.ExternDataDeclaration{} = True+isTypeDeclaration P.TypeSynonymDeclaration{} = True isTypeDeclaration _ = False  isTypeClassDeclaration :: P.Declaration -> Bool-isTypeClassDeclaration (P.TypeClassDeclaration _ _ _) = True+isTypeClassDeclaration P.TypeClassDeclaration{} = True isTypeClassDeclaration _ = False  isTypeInstanceDeclaration :: P.Declaration -> Bool-isTypeInstanceDeclaration (P.TypeInstanceDeclaration _ _ _ _) = True+isTypeInstanceDeclaration P.TypeInstanceDeclaration{} = True isTypeInstanceDeclaration _ = False  inputFile :: Term FilePath@@ -147,7 +147,7 @@ termInfo :: TermInfo termInfo = defTI   { termName = "docgen"-  , version  = showVersion $ Paths.version+  , version  = showVersion Paths.version   , termDoc  = "Generate Markdown documentation from PureScript extern files"   } 
prelude/prelude.purs view
@@ -162,17 +162,14 @@   -- Referential equality   data Ref a = Ref a -  foreign import refEq "function refEq(r1) {\-                       \  return function(r2) {\-                       \    return r1.values[0] === r2.values[0];\-                       \  };\-                       \}" :: forall a. Ref a -> Ref a -> Boolean--  foreign import refIneq "function refIneq(r1) {\-                         \  return function(r2) {\-                         \    return r1.values[0] !== r2.values[0];\-                         \  };\-                         \}" :: forall a. Ref a -> Ref a -> Boolean+  liftRef :: forall a b. (a -> a -> b) -> Ref a -> Ref a -> b+  liftRef f (Ref x) (Ref y) = f x y+  +  refEq :: forall a. Ref a -> Ref a -> Boolean+  refEq = liftRef unsafeRefEq+  +  refIneq :: forall a. Ref a -> Ref a -> Boolean+  refIneq = liftRef unsafeRefIneq    foreign import unsafeRefEq "function unsafeRefEq(r1) {\                              \  return function(r2) {\@@ -356,9 +353,10 @@                       \  };\                       \}" :: String -> String -> String -module Monoid where+module Data.Monoid where    import Prelude+  import Data.Array (foldl)    infixr 6 <> @@ -372,16 +370,15 @@    instance Monoid [a] where     mempty = []-    (<>) = Arrays.concat+    (<>) = Data.Array.concat    mconcat :: forall m. (Monoid m) => [m] -> m-  mconcat [] = mempty-  mconcat (m:ms) = m <> mconcat ms+  mconcat = foldl (<>) mempty -module Monad where+module Control.Monad where    import Prelude-  import Arrays+  import Data.Array    replicateM :: forall m a. (Monad m) => Number -> m a -> m [a]   replicateM 0 _ = return []@@ -428,7 +425,7 @@   when true m = m   when false _ = return {} -module Maybe where+module Data.Maybe where    import Prelude @@ -458,7 +455,7 @@     show (Just x) = "Just " ++ (show x)     show Nothing = "Nothing" -module Either where+module Data.Either where    import Prelude @@ -485,24 +482,18 @@     show (Left x) = "Left " ++ (show x)     show (Right y) = "Right " ++ (show y) -module Arrays where+module Data.Array where    import Prelude-  import Maybe--  head :: forall a. [a] -> a-  head (x : _) = x--  headSafe :: forall a. [a] -> Maybe a-  headSafe (x : _) = Just x-  headSafe _ = Nothing+  import Data.Maybe -  tail :: forall a. [a] -> [a]-  tail (_ : xs) = xs+  head :: forall a. [a] -> Maybe a+  head (x : _) = Just x+  head _ = Nothing -  tailSafe :: forall a. [a] -> Maybe [a]-  tailSafe (_ : xs) = Just xs-  tailSafe _ = Nothing+  tail :: forall a. [a] -> Maybe [a]+  tail (_ : xs) = Just xs+  tail _ = Nothing    map :: forall a b. (a -> b) -> [a] -> [b]   map _ [] = []@@ -512,9 +503,9 @@   foldr f a (b : bs) = f (foldr f a bs) b   foldr _ a [] = a -  foldl :: forall a b. (a -> b -> b) -> b -> [a] -> b+  foldl :: forall a b. (b -> a -> b) -> b -> [a] -> b   foldl _ b [] = b-  foldl f b (a:as) = foldl f (f a b) as+  foldl f b (a:as) = foldl f (f b a) as    foreign import length "function length(xs) {\                         \  return xs.length;\@@ -582,16 +573,39 @@                       \  return l1;\                       \}" :: forall a. [a] -> [a] -  foreign import splice "function splice(s) {\-                        \  return function(e) {\-                        \    return function(l1) {\-                        \      return function(l2) {\-                        \        return l2.splice(s, e, l1);\-                        \      }; \-                        \    }; \-                        \  };\-                        \}":: forall a. Number -> Number -> [a] -> [a] -> [a]+  foreign import insertAt +    "function insertAt(index) {\+    \  return function(a) {\+    \    return function(l) {\+    \      var l1 = l.slice();\+    \      l1.splice(index, 0, a);\+    \      return l1;\+    \    }; \+    \  };\+    \}":: forall a. Number -> a -> [a] -> [a] +  foreign import deleteAt +    "function deleteAt(index) {\+    \  return function(n) {\+    \    return function(l) {\+    \      var l1 = l.slice();\+    \      l1.splice(index, n);\+    \      return l1;\+    \    }; \+    \  };\+    \}":: forall a. Number -> Number -> [a] -> [a]++  foreign import updateAt +    "function updateAt(index) {\+    \  return function(a) {\+    \    return function(l) {\+    \      var l1 = l.slice();\+    \      l1[index] = a;\+    \      return l1;\+    \    }; \+    \  };\+    \}":: forall a. Number -> a -> [a] -> [a]+   infixr 6 :    (:) :: forall a. a -> [a] -> [a]@@ -647,11 +661,19 @@   instance Prelude.Alternative [] where     empty = []     (<|>) = concat+    +module Data.Array.Unsafe where -module Tuples where+  head :: forall a. [a] -> a+  head (x : _) = x +  tail :: forall a. [a] -> [a]+  tail (_ : xs) = xs++module Data.Tuple where+   import Prelude-  import Arrays+  import Data.Array    data Tuple a b = Tuple a b @@ -672,7 +694,7 @@     Tuple as bs -> Tuple (a : as) (b : bs)   unzip [] = Tuple [] [] -module String where+module Data.String where    foreign import lengthS "function lengthS(s) {\                          \  return s.length;\@@ -752,7 +774,7 @@                       \  return s.trim();\                       \}" :: String -> String -module Regex where+module Data.String.Regex where    foreign import data Regex :: * @@ -907,7 +929,7 @@   foreign import sqrt1_2 "var sqrt1_2 = Math.SQRT1_2;" :: Number   foreign import sqrt2   "var sqrt2   = Math.SQRT2;"   :: Number -module Eff where+module Control.Monad.Eff where    foreign import data Eff :: # ! -> * -> * @@ -936,29 +958,29 @@     (>>=) = bindEff    foreign import untilE "function untilE(f) {\-			\  return function() {\-			\    while (!f()) { }\-			\    return {};\-			\  };\+                        \  return function() {\+                        \    while (!f()) { }\+                        \    return {};\+                        \  };\                         \}" :: forall e. Eff e Boolean -> Eff e {}    foreign import whileE "function whileE(f) {\-			\  return function(a) {\-			\    return function() {\-			\      while (f()) {\+                        \  return function(a) {\+                        \    return function() {\+                        \      while (f()) {\                         \        a();\                         \      }\-			\      return {};\+                        \      return {};\                         \    };\                         \  };\                         \}" :: forall e a. Eff e Boolean -> Eff e a -> Eff e {}    foreign import forE "function forE(lo) {\-	              \  return function(hi) {\-	              \    return function(f) {\-	              \      return function() {\-	              \        for (var i = lo; i < hi; i++) {\-		      \          f(i)();\+                      \  return function(hi) {\+                      \    return function(f) {\+                      \      return function() {\+                      \        for (var i = lo; i < hi; i++) {\+                      \          f(i)();\                       \        }\                       \      };\                       \    };\@@ -967,9 +989,9 @@     foreign import foreachE "function foreachE(as) {\-	                  \  return function(f) {\-	                  \    for (var i = 0; i < as.length; i++) {\-		          \      f(as[i])();\+                          \  return function(f) {\+                          \    for (var i = 0; i < as.length; i++) {\+                          \      f(as[i])();\                           \    }\                           \  };\                           \}" :: forall e a. [a] -> (a -> Eff e {}) -> Eff e {}@@ -977,7 +999,7 @@  module Random where -  import Eff+  import Control.Monad.Eff    foreign import data Random :: ! @@ -985,9 +1007,9 @@                         \  return Math.random();\                         \}" :: forall e. Eff (random :: Random | e) Number -module Errors where+module Control.Monad.Error where -  import Eff+  import Control.Monad.Eff    foreign import data Error :: * -> ! @@ -1009,9 +1031,9 @@                             \  };\                             \}" :: forall e r a. (e -> Eff r a) -> Eff (err :: Error e | r) a -> Eff r a -module IORef where+module Data.IORef where -  import Eff+  import Control.Monad.Eff    foreign import data Ref :: ! @@ -1052,10 +1074,10 @@                                 \  return f;\                                 \}" :: forall eff a. Eff (ref :: Ref | eff) a -> Eff eff a -module Trace where+module Debug.Trace where    import Prelude-  import Eff+  import Control.Monad.Eff    foreign import data Trace :: ! @@ -1069,9 +1091,9 @@   print :: forall a r. (Prelude.Show a) => a -> Eff (trace :: Trace | r) {}   print o = trace (show o) -module ST where+module Control.Monad.ST where -  import Eff+  import Control.Monad.Eff    foreign import data ST :: * -> ! @@ -1145,9 +1167,9 @@                             \  return f;\                             \}" :: forall a r. (forall h. Eff (st :: ST h | r) (STArray h a)) -> Eff r [a] -module Enum where+module Data.Enum where -  import Maybe+  import Data.Maybe    class Enum a where     toEnum :: Number -> Maybe a
psc/Main.hs view
@@ -28,7 +28,7 @@ preludeFilename = Paths.getDataFileName "prelude/prelude.purs"  readInput :: Maybe [FilePath] -> IO (Either ParseError [P.Module])-readInput Nothing = getContents >>= return . P.runIndentParser "" P.parseModules+readInput Nothing = P.runIndentParser "" P.parseModules <$> getContents readInput (Just input) = fmap (fmap concat . sequence) $ forM input $ \inputFile -> do   text <- U.readFile inputFile   return $ P.runIndentParser inputFile P.parseModules text@@ -118,7 +118,7 @@ termInfo :: TermInfo termInfo = defTI   { termName = "psc"-  , version  = showVersion $ Paths.version+  , version  = showVersion Paths.version   , termDoc  = "Compiles PureScript to Javascript"   } 
+ psci/Commands.hs view
@@ -0,0 +1,68 @@+-----------------------------------------------------------------------------+--+-- Module      :  Commands+-- Copyright   :  (c) Phil Freeman 2014+-- License     :  MIT+--+-- Maintainer  :  Phil Freeman <paf31@cantab.net>+-- Stability   :  experimental+-- Portability :+--+-- |+-- Commands for PSCI.+--+-----------------------------------------------------------------------------++module Commands where++import Language.PureScript++-- |+-- Valid Meta-commands for PSCI+--+data Command+  -- |+  -- A purescript expression+  --+  = Expression Value+  -- |+  -- Show the help command+  --+  | Help+  -- |+  -- Import a module from a loaded file+  --+  | Import ModuleName+  -- |+  -- Load a file for use with importing+  --+  | LoadFile FilePath+  -- |+  -- Exit PSCI+  --+  | Quit+  -- |+  -- Reset the state of the REPL+  --+  | Reset+  -- |+  -- Binds a value to a name+  --+  | Let (Value -> Value)+  -- |+  -- Find the type of an expression+  --+  | TypeOf Value++-- |+-- The help menu.+--+help :: [[String]]+help =+  [ [":?          ", "Show this help menu"]+  , [":i <module> ", "Import <module> for use in PSCI"]+  , [":m <file>   ", "Load <file> for importing"]+  , [":q          ", "Quit PSCi"]+  , [":r          ", "Reset"]+  , [":t <expr>   ", "Show the type of <expr>"]+  ]
psci/Main.hs view
@@ -13,7 +13,7 @@ -- ----------------------------------------------------------------------------- -{-# LANGUAGE FlexibleContexts #-}+{-# LANGUAGE DoAndIfThenElse, FlexibleContexts #-}  module Main where @@ -23,22 +23,29 @@ import Control.Monad import Control.Monad.Trans.Class import Control.Monad.Trans.Maybe (MaybeT(..), runMaybeT)-import Control.Monad.Trans.State+import Control.Monad.Trans.State.Strict -import Data.List (intercalate, isPrefixOf, nub, sort)+import Data.List (intercalate, isPrefixOf, nub, sortBy) import Data.Maybe (mapMaybe) import Data.Traversable (traverse)+import Data.Version (showVersion) +import Parser+ import System.Console.Haskeline-import System.Directory (findExecutable)+import System.Directory (doesFileExist, findExecutable, getHomeDirectory) import System.Exit import System.Environment.XDG.BaseDir+import System.FilePath ((</>), isPathSeparator)+import qualified System.Console.CmdTheLine as Cmd import System.Process +import Text.Parsec (ParseError)++import qualified Data.Map as M import qualified Language.PureScript as P import qualified Paths_purescript as Paths import qualified System.IO.UTF8 as U (readFile)-import qualified Text.Parsec as Parsec (Parsec, eof)  -- | -- The PSCI state.@@ -46,48 +53,45 @@ -- The let bindings are partial, -- because it makes more sense to apply the binding to the final evaluated expression. ---data PSCI = PSCI [P.ProperName] [P.Module] [P.Value -> P.Value]+data PSCiState = PSCiState+  { psciImportedFilenames   :: [FilePath]+  , psciImportedModuleNames :: [P.ModuleName]+  , psciLoadedModules       :: [P.Module]+  , psciLetBindings         :: [P.Value -> P.Value]+  }  -- State helpers  -- |--- Synonym to be more descriptive.--- This is just @lift@----inputTToState :: InputT IO a -> StateT PSCI (InputT IO) a-inputTToState = lift---- |--- Synonym to be more descriptive.--- This is just @lift . lift@+-- Updates the state to have more imported modules. ---ioToState :: IO a -> StateT PSCI (InputT IO) a-ioToState = lift . lift+updateImportedFiles :: FilePath -> PSCiState -> PSCiState+updateImportedFiles filename st = st { psciImportedFilenames = filename : psciImportedFilenames st }  -- | -- Updates the state to have more imported modules. ---updateImports :: String -> PSCI -> PSCI-updateImports name (PSCI i m b) = PSCI (i ++ [P.ProperName name]) m b+updateImports :: P.ModuleName -> PSCiState -> PSCiState+updateImports name st = st { psciImportedModuleNames = name : psciImportedModuleNames st }  -- | -- Updates the state to have more loaded files. ---updateModules :: [P.Module] -> PSCI -> PSCI-updateModules modules (PSCI i m b) = PSCI i (m ++ modules) b+updateModules :: [P.Module] -> PSCiState -> PSCiState+updateModules modules st = st { psciLoadedModules = psciLoadedModules st ++ modules }  -- | -- Updates the state to have more let bindings. ---updateLets :: (P.Value -> P.Value) -> PSCI -> PSCI-updateLets name (PSCI i m b) = PSCI i m (b ++ [name])+updateLets :: (P.Value -> P.Value) -> PSCiState -> PSCiState+updateLets name st = st { psciLetBindings = psciLetBindings st ++ [name] }  -- File helpers -- | -- Load the necessary modules. ---defaultImports :: [P.ProperName]-defaultImports = [P.ProperName "Prelude"]+defaultImports :: [P.ModuleName]+defaultImports = [P.ModuleName [P.ProperName "Prelude"]]  -- | -- Locates the node executable.@@ -95,7 +99,7 @@ -- findNodeProcess :: IO (Maybe String) findNodeProcess = runMaybeT . msum $ map (MaybeT . findExecutable) names-    where names = ["nodejs", "node"]+  where names = ["nodejs", "node"]  -- | -- Grabs the filename where the history is stored.@@ -113,10 +117,14 @@ -- Loads a file for use with imports. -- loadModule :: FilePath -> IO (Either String [P.Module])-loadModule moduleFile = do-  moduleText <- U.readFile moduleFile-  return . either (Left . show) Right $ P.runIndentParser "" P.parseModules moduleText+loadModule filename = either (Left . show) Right . P.runIndentParser filename P.parseModules <$> U.readFile filename +-- |+-- Expands tilde in path.+--+expandTilde :: FilePath -> IO FilePath+expandTilde ('~':p:rest) | isPathSeparator p = (</> rest) <$> getHomeDirectory+expandTilde p = return p -- Messages  -- |@@ -154,23 +162,27 @@ -- | -- Loads module, function, and file completions. ---completion :: [P.Module] -> CompletionFunc IO-completion ms = completeWord Nothing " \t\n\r" findCompletions+completion :: CompletionFunc (StateT PSCiState IO)+completion = completeWord Nothing " \t\n\r" findCompletions   where-  findCompletions :: String -> IO [Completion]+  findCompletions :: String -> StateT PSCiState IO [Completion]   findCompletions str = do+    ms <- psciLoadedModules <$> get     files <- listFiles str-    let names = nub [ show qual-                    | P.Module moduleName ds <- ms-                    , ident <- mapMaybe getDeclName ds-                    , qual <- [ P.Qualified Nothing ident-                              , P.Qualified (Just moduleName) ident]-                    ]-    let matches = sort $ filter (isPrefixOf str) names-    return $ map simpleCompletion matches ++ files+    let matches = filter (isPrefixOf str) (names ms)+    return $ sortBy sorter $ map simpleCompletion matches ++ files   getDeclName :: P.Declaration -> Maybe P.Ident   getDeclName (P.ValueDeclaration ident _ _ _) = Just ident   getDeclName _ = Nothing+  names :: [P.Module] -> [String]+  names ms = nub [ show qual+              | P.Module moduleName ds <- ms+              , ident <- mapMaybe getDeclName ds+              , qual <- [ P.Qualified Nothing ident+                        , P.Qualified (Just moduleName) ident]+              ]+  sorter :: Completion -> Completion -> Ordering+  sorter (Completion _ d1 _) (Completion _ d2 _) = compare d1 d2  -- Compilation @@ -182,93 +194,129 @@ -- | -- Makes a volatile module to execute the current expression. ---createTemporaryModule :: [P.ProperName] -> [P.Value -> P.Value] -> P.Value -> P.Module-createTemporaryModule imports lets value =+createTemporaryModule :: Bool -> [P.ModuleName] -> [P.Value -> P.Value] -> P.Value -> P.Module+createTemporaryModule exec imports lets value =   let     moduleName = P.ModuleName [P.ProperName "Main"]     importDecl m = P.ImportDeclaration m Nothing-    traceModule = P.ModuleName [P.ProperName "Trace"]+    traceModule = P.ModuleName [P.ProperName "Debug", P.ProperName "Trace"]     trace = P.Var (P.Qualified (Just traceModule) (P.Ident "print"))     value' = foldr ($) value lets-    mainDecl = P.ValueDeclaration (P.Ident "main") [] Nothing (P.App trace value')+    itDecl = P.ValueDeclaration (P.Ident "it") [] Nothing value'+    mainDecl = P.ValueDeclaration (P.Ident "main") [] Nothing (P.App trace (P.Var (P.Qualified Nothing (P.Ident "it"))))   in-    P.Module moduleName $ map (importDecl . P.ModuleName . return) imports ++ [mainDecl]+    P.Module moduleName $ map importDecl imports ++ if exec then [itDecl, mainDecl] else [itDecl]  -- | -- Takes a value declaration and evaluates it with the current state. ---handleDeclaration :: P.Value -> PSCI -> InputT IO ()-handleDeclaration value (PSCI imports loadedModules lets) = do-  let m = createTemporaryModule imports lets value-  case P.compile options (loadedModules ++ [m]) of+handleDeclaration :: P.Value -> PSCiState -> InputT (StateT PSCiState IO) ()+handleDeclaration value st = do+  let m = createTemporaryModule True (psciImportedModuleNames st) (psciLetBindings st) value+  case P.compile options (psciLoadedModules st ++ [m]) of     Left err -> outputStrLn err     Right (js, _, _) -> do-      process <- lift findNodeProcess-      result <- lift $ traverse (\node -> readProcessWithExitCode node [] js) process+      process <- lift . lift $ findNodeProcess+      result <- lift . lift $ traverse (\node -> readProcessWithExitCode node [] js) process       case result of         Just (ExitSuccess,   out, _)   -> outputStrLn out         Just (ExitFailure _, _,   err) -> outputStrLn err         Nothing                        -> outputStrLn "Couldn't find node.js" --- Parser helpers- -- |--- Parser for our PSCI version of @let@.--- This is essentially let from do-notation.--- However, since we don't support the @Eff@ monad, we actually want the normal @let@.+-- Takes a value and prints its type ---parseLet :: Parsec.Parsec String P.ParseState (P.Value -> P.Value)-parseLet = P.Let <$> (P.reserved "let" *> P.indented *> P.parseBinder)-                 <*> (P.indented *> P.reservedOp "=" *> P.parseValue)+handleTypeOf :: P.Value -> PSCiState -> InputT (StateT PSCiState IO) ()+handleTypeOf value st = do+  let m = createTemporaryModule False (psciImportedModuleNames st) (psciLetBindings st) value+  case P.compile options { P.optionsMain = Nothing } (psciLoadedModules st ++ [m]) of+    Left err -> outputStrLn err+    Right (_, _, env') ->+      case M.lookup (P.ModuleName [P.ProperName "Main"], P.Ident "it") (P.names env') of+        Just (ty, _) -> outputStrLn . P.prettyPrintType $ ty+        Nothing -> outputStrLn "Could not find type" +-- Commands+ -- |--- Parser for any other valid expression.+-- Parses the input and returns either a Metacommand or an expression. ---parseExpression :: Parsec.Parsec String P.ParseState P.Value-parseExpression = P.whiteSpace *> P.parseValue <* Parsec.eof---- Commands+getCommand :: InputT (StateT PSCiState IO) (Either ParseError (Maybe Command))+getCommand = do+  firstLine <- getInputLine "> "+  case firstLine of+    Nothing -> return (Right Nothing)+    Just s@ (':' : _) -> return . either Left (Right . Just) $ parseCommand s -- The start of a command+    Just s -> either Left (Right . Just) . parseCommand <$> go [s]+  where+    go :: [String] -> InputT (StateT PSCiState IO) String+    go ls = maybe (return . unlines $ reverse ls) (go . (:ls)) =<< getInputLine "  "  -- | -- Performs an action for each meta-command given, and also for expressions.. ---handleCommand :: Command -> StateT PSCI (InputT IO) ()-handleCommand Empty = return ()-handleCommand (Expression ls) =-  case P.runIndentParser "" parseLet (unlines ls) of-    Left _ ->-      case P.runIndentParser "" parseExpression (unlines ls) of-        Left err -> inputTToState $ outputStrLn (show err)-        Right decl -> get >>= inputTToState . handleDeclaration decl-    Right l -> modify (updateLets l)-handleCommand Help = inputTToState $ outputStrLn helpMessage-handleCommand (Import moduleName) = modify (updateImports moduleName)+handleCommand :: Command -> InputT (StateT PSCiState IO) ()+handleCommand (Expression val) = lift get >>= handleDeclaration val+handleCommand (Let l) = lift $ modify (updateLets l)+handleCommand Help = outputStrLn helpMessage+handleCommand (Import moduleName) = lift $ modify (updateImports moduleName) handleCommand (LoadFile filePath) = do-  mf <- ioToState $ loadModule filePath-  case mf of-    Left err -> inputTToState $ outputStrLn err-    Right mf' -> modify (updateModules mf')-handleCommand Reload = do-  (Right prelude) <- ioToState $ getPreludeFilename >>= loadModule-  put (PSCI defaultImports prelude [])-handleCommand _ = inputTToState $ outputStrLn "Unknown command"+  absPath <- lift . lift $ expandTilde filePath+  exists <- lift . lift $ doesFileExist absPath+  if exists then do+    lift $ modify (updateImportedFiles absPath)+    either outputStrLn (lift . modify . updateModules) =<< (lift . lift $ loadModule absPath)+  else+    outputStrLn $ "Couldn't locate: " ++ filePath+handleCommand Reset = do+  preludeFilename <- lift . lift $ getPreludeFilename+  files <- psciImportedFilenames <$> lift get+  modulesOrFirstError <- fmap concat . sequence <$> mapM (lift . lift . loadModule) (preludeFilename : files)+  case modulesOrFirstError of+    Left err -> lift . lift $ putStrLn err >> exitFailure+    Right modules -> lift $ put (PSCiState (preludeFilename : files) defaultImports modules [])+handleCommand (TypeOf val) = lift get >>= handleTypeOf val+handleCommand _ = outputStrLn "Unknown command" +inputFiles :: Cmd.Term [FilePath]+inputFiles = Cmd.value $ Cmd.posAny [] $ Cmd.posInfo { Cmd.posName = "file(s)"+                                                     , Cmd.posDoc = "Optional .purs files to load on start" }+ -- | -- The PSCI main loop. ---main :: IO ()-main = do+loop :: [FilePath] -> IO ()+loop files = do   preludeFilename <- getPreludeFilename-  (Right prelude) <- loadModule preludeFilename-  historyFilename <- getHistoryFilename-  let settings = defaultSettings {historyFile = Just historyFilename}-  runInputT (setComplete (completion prelude) settings) $ do-    outputStrLn prologueMessage-    evalStateT go (PSCI defaultImports prelude [])-  where-    go :: StateT PSCI (InputT IO) ()-    go = do-      c <- inputTToState getCommand-      case c of-        Quit -> inputTToState $ outputStrLn quitMessage-        _    -> handleCommand c >> go+  modulesOrFirstError <- fmap concat . sequence <$> mapM loadModule (preludeFilename : files)+  case modulesOrFirstError of+    Left err -> putStrLn err >> exitFailure+    Right modules -> do+      historyFilename <- getHistoryFilename+      let settings = defaultSettings {historyFile = Just historyFilename}+      flip evalStateT (PSCiState (preludeFilename : files) defaultImports modules []) . runInputT (setComplete completion settings) $ do+        outputStrLn prologueMessage+        go+      where+        go :: InputT (StateT PSCiState IO) ()+        go = do+          c <- getCommand+          case c of+            Left err -> outputStrLn (show err) >> go+            Right Nothing -> go+            Right (Just Quit) -> outputStrLn quitMessage+            Right (Just c') -> handleCommand c' >> go++term :: Cmd.Term (IO ())+term = loop <$> inputFiles++termInfo :: Cmd.TermInfo+termInfo = Cmd.defTI+  { Cmd.termName = "psci"+  , Cmd.version  = showVersion Paths.version+  , Cmd.termDoc  = "Interactive mode for PureScript"+  }++main :: IO ()+main = Cmd.run (term, termInfo)+
+ psci/Parser.hs view
@@ -0,0 +1,92 @@+-----------------------------------------------------------------------------+--+-- Module      :  Parser+-- Copyright   :  (c) Phil Freeman 2014+-- License     :  MIT+--+-- Maintainer  :  Phil Freeman <paf31@cantab.net>+-- Stability   :  experimental+-- Portability :+--+-- |+-- Parser for PSCI.+--+-----------------------------------------------------------------------------++module Parser (+    parseCommand+  ) where++import Commands++import Data.Char (isSpace)++import Control.Applicative hiding (many)++import Text.Parsec hiding ((<|>))++import qualified Language.PureScript as P++-- |+-- PSCI version of @let@.+-- This is essentially let from do-notation.+-- However, since we don't support the @Eff@ monad,+-- we actually want the normal @let@.+--+psciLet :: Parsec String P.ParseState Command+psciLet = Let <$> (P.Let <$> (P.reserved "let" *> P.indented *> P.parseBinder)+                         <*> (P.indented *> P.reservedOp "=" *> P.parseValue))++-- |+-- Parses PSCI metacommands or expressions input from the user.+--+parseCommand :: String -> Either ParseError Command+parseCommand = P.runIndentParser "" $ choice+                    [ P.whiteSpace *> char ':' *> (psciHelp <|> psciImport <|> psciLoadFile <|> psciQuit <|> psciReload <|> psciTypeOf)+                    , try psciLet+                    , psciExpression+                    ] <* eof++-- |+-- Parses expressions entered at the PSCI repl.+--+psciExpression :: Parsec String P.ParseState Command+psciExpression = Expression <$> P.parseValue++-- |+-- Parses 'Commands.Help' command.+--+psciHelp :: Parsec String P.ParseState Command+psciHelp = Help <$ char '?'++-- |+-- Parses 'Commands.Import' command.+--+psciImport :: Parsec String P.ParseState Command+psciImport = Import <$> (char 'i' *> P.whiteSpace *> P.moduleName)++-- |+-- Parses 'Commands.LoadFile' command.+--+psciLoadFile :: Parsec String P.ParseState Command+psciLoadFile = LoadFile . trimEnd <$> (char 'm' *> P.whiteSpace *> manyTill anyChar eof)+  where+  trimEnd = reverse . dropWhile isSpace . reverse++-- |+-- Parses 'Commands.Quit' command.+--+psciQuit :: Parsec String P.ParseState Command+psciQuit = Quit <$ char 'q'++-- |+-- Parses 'Commands.Reload' command.+--+psciReload :: Parsec String P.ParseState Command+psciReload = Reset <$ char 'r'++-- |+-- Parses 'Commands.TypeOf' command.+--+psciTypeOf :: Parsec String P.ParseState Command+psciTypeOf = TypeOf <$> (char 't' *> P.whiteSpace *> P.parseValue)
purescript.cabal view
@@ -1,5 +1,5 @@ name: purescript-version: 0.4.2+version: 0.4.2.1 cabal-version: >=1.8 build-type: Custom license: MIT@@ -84,14 +84,15 @@     ghc-options: -Wall -O2 -fno-warn-unused-do-bind  executable psci-    build-depends: base >=4 && <5, containers -any, directory -any,+    build-depends: base >=4 && <5, containers -any, directory -any, filepath -any,                    mtl -any, parsec -any, haskeline <=0.7.1.1, purescript -any,                    syb -any, transformers -any, utf8-string -any, process -any,-                   xdg-basedir -any+                   xdg-basedir -any, cmdtheline -any     main-is: Main.hs     buildable: True     hs-source-dirs: psci-    other-modules:+    other-modules: Commands+                   Parser     ghc-options: -Wall -O2  executable docgen
src/Data/Generics/Extras.hs view
@@ -18,6 +18,7 @@ module Data.Generics.Extras where  import Data.Data+import Data.Maybe (fromMaybe)  -- | -- Apply a top-down monadic transformation everywhere@@ -26,3 +27,37 @@ everywhereM' f x = do   y <- f x   gmapM (everywhereM' f) y++-- |+-- Apply a top-down transformation, mutating a state when descending from parents to children+--+-- For example, if we want to relabel bound variables with a different data constructor, we can do so:+--+-- > data Expr = Var String+-- >           | Lam String Test+-- >           | App Test Test+-- >           | LocalVar String deriving (Show, Data, Typeable)+-- >+-- > test = App (Lam "a" (App (Var "a") (Var "b"))) (Var "a")+-- >+-- > varsToLocals :: Expr -> Expr+-- > varsToLocals = everywhereWithContext' [] (mkS go)+-- >   where+-- >   go locals (Var v) | v `elem` locals = (locals, LocalVar v)+-- >   go locals lam@(Lam local _) = (local : locals, lam)+-- >   go locals other = (locals, other)+--+everywhereWithContext' :: (Data d) => s -> (forall d1. (Data d1) => s -> d1 -> (s, d1)) -> d -> d+everywhereWithContext' s0 f x =+  let (s, y) = f s0 x in+  gmapT (everywhereWithContext' s f) y++-- |+-- Make a stateful transformation function+--+mkS :: (Data a, Data b) => (s -> a -> (s, a)) -> s -> b -> (s, b)+mkS f s b = fromMaybe (s, b) $ do+  a <- cast b+  let (s', a') = f s a+  b' <- cast a'+  return (s', b')
src/Language/PureScript.hs view
@@ -22,6 +22,7 @@ import Language.PureScript.Names as P import Language.PureScript.Parser as P import Language.PureScript.CodeGen as P+import Language.PureScript.CodeGen.Common as P import Language.PureScript.TypeChecker as P import Language.PureScript.Pretty as P import Language.PureScript.Sugar as P@@ -30,10 +31,9 @@ import Language.PureScript.DeadCodeElimination as P  import Data.List (intercalate)-import Data.Maybe (mapMaybe, fromMaybe)-import Control.Monad (when, forM)+import Data.Maybe (mapMaybe) import Control.Monad.State.Lazy-import Control.Applicative ((<$>), (<|>))+import Control.Applicative ((<$>)) import qualified Data.Map as M  -- |@@ -59,24 +59,20 @@ compile opts ms = do   sorted <- sortModules ms   desugared <- desugar sorted-  (elaborated, env) <- runCheck $ forM desugared $ \(Module moduleName decls) -> do-    modify (\s -> s { checkCurrentModule = Just moduleName })-    Module moduleName <$> typeCheckAll mainModuleIdent moduleName decls+  (elaborated, env) <- runCheck $ forM desugared $ \(Module moduleName' decls) -> do+    modify (\s -> s { checkCurrentModule = Just moduleName' })+    Module moduleName' <$> typeCheckAll mainModuleIdent moduleName' decls   regrouped <- createBindingGroupsModule . collapseBindingGroupsModule $ elaborated-  let entryPoints = (ModuleName . splitProperNames) `map` optionsModules opts+  let entryPoints = moduleNameFromString `map` optionsModules opts   let elim = if null entryPoints then regrouped else eliminateDeadCode env entryPoints regrouped   let js = mapMaybe (flip (moduleToJs opts) env) elim-  let exts = intercalate "\n" . map (flip moduleToPs env) $ elim-  js' <- case optionsMain opts of-    Just mainModuleName -> do-      when ((ModuleName [ProperName mainModuleName], Ident "main") `M.notMember` (names env)) $-        Left $ mainModuleName ++ ".main is undefined"-      return $ js ++ [JSApp (JSAccessor "main" (JSAccessor mainModuleName (JSVar "_ps"))) []]+  let exts = intercalate "\n" . map (`moduleToPs` env) $ elim+  js' <- case mainModuleIdent of+    Just mmi -> do+      when ((mmi, Ident "main") `M.notMember` names env) $+        Left $ show mmi ++ ".main is undefined"+      return $ js ++ [JSApp (JSAccessor "main" (JSAccessor (moduleNameToJs mmi) (JSVar "_ps"))) []]     _ -> return js-  return (prettyPrintJS [(wrapExportsContainer opts js')], exts, env)+  return (prettyPrintJS [wrapExportsContainer opts js'], exts, env)   where-  mainModuleIdent = ModuleName . splitProperNames <$> optionsMain opts-  splitProperNames s = case dropWhile (== '.') s of-    "" -> []-    s' -> ProperName w : splitProperNames s''-      where (w, s'') = break (== '.') s'+  mainModuleIdent = moduleNameFromString <$> optionsMain opts
src/Language/PureScript/CodeGen/Common.hs view
@@ -69,64 +69,66 @@ -- nameIsJsReserved :: String -> Bool nameIsJsReserved name =-  elem name [ "abstract"-            , "boolean"-            , "break"-            , "byte"-            , "case"-            , "catch"-            , "char"-            , "class"-            , "const"-            , "continue"-            , "debugger"-            , "default"-            , "delete"-            , "do"-            , "double"-            , "else"-            , "enum"-            , "export"-            , "extends"-            , "final"-            , "finally"-            , "float"-            , "for"-            , "function"-            , "goto"-            , "if"-            , "implements"-            , "import"-            , "in"-            , "instanceof"-            , "int"-            , "interface"-            , "let"-            , "long"-            , "native"-            , "new"-            , "package"-            , "private"-            , "protected"-            , "public"-            , "return"-            , "short"-            , "static"-            , "super"-            , "switch"-            , "synchronized"-            , "this"-            , "throw"-            , "throws"-            , "transient"-            , "try"-            , "typeof"-            , "var"-            , "void"-            , "volatile"-            , "while"-            , "with"-            , "yield" ]+  name `elem` [ "abstract"+              , "arguments"+              , "boolean"+              , "break"+              , "byte"+              , "case"+              , "catch"+              , "char"+              , "class"+              , "const"+              , "continue"+              , "debugger"+              , "default"+              , "delete"+              , "do"+              , "double"+              , "else"+              , "enum"+              , "eval"+              , "export"+              , "extends"+              , "final"+              , "finally"+              , "float"+              , "for"+              , "function"+              , "goto"+              , "if"+              , "implements"+              , "import"+              , "in"+              , "instanceof"+              , "int"+              , "interface"+              , "let"+              , "long"+              , "native"+              , "new"+              , "package"+              , "private"+              , "protected"+              , "public"+              , "return"+              , "short"+              , "static"+              , "super"+              , "switch"+              , "synchronized"+              , "this"+              , "throw"+              , "throws"+              , "transient"+              , "try"+              , "typeof"+              , "var"+              , "void"+              , "volatile"+              , "while"+              , "with"+              , "yield" ]  moduleNameToJs :: ModuleName -> String moduleNameToJs (ModuleName pns) = intercalate "_" (runProperName `map` pns)
src/Language/PureScript/CodeGen/Externs.hs view
@@ -30,14 +30,14 @@ -- moduleToPs :: Module -> Environment -> String moduleToPs (Module mn decls) env =-  "module " ++ (runModuleName mn) ++ " where\n" +++  "module " ++ runModuleName mn ++ " where\n" ++   (intercalate "\n" . map ("  " ++) . concatMap (declToPs mn env) $ decls)  declToPs :: ModuleName -> Environment -> Declaration -> [String] declToPs path env (ValueDeclaration name _ _ _) = maybeToList $ do   (ty, _) <- M.lookup (path, name) $ names env   return $ "foreign import " ++ show name ++ " :: " ++ prettyPrintType ty-declToPs path env (BindingGroupDeclaration vals) = do+declToPs path env (BindingGroupDeclaration vals) =   flip mapMaybe vals $ \(name, _) -> do     (ty, _) <- M.lookup (path, name) $ names env     return $ "foreign import " ++ show name ++ " :: " ++ prettyPrintType ty
src/Language/PureScript/CodeGen/JS.hs view
@@ -23,7 +23,6 @@ ) where  import Data.Maybe (fromMaybe, mapMaybe)-import Data.List (sortBy) import Data.Function (on) import Data.Data (Data) import Data.Generics (mkQ, everything)@@ -38,7 +37,6 @@ import Language.PureScript.Names import Language.PureScript.Scope import Language.PureScript.Declarations-import Language.PureScript.Pretty.Common import Language.PureScript.CodeGen.Monad import Language.PureScript.Options import Language.PureScript.CodeGen.JS.AST as AST@@ -57,16 +55,16 @@     [] -> Nothing     _ -> Just $ JSAssignment (JSAccessor (moduleNameToJs name) (JSVar "_ps")) $            JSApp (JSFunction Nothing ["module"] (JSBlock $ jsDecls ++ [JSReturn $ JSVar "module"]))-                 [(JSBinary Or (JSAccessor (moduleNameToJs name) (JSVar "_ps")) (JSObjectLiteral []))]+                 [JSBinary Or (JSAccessor (moduleNameToJs name) (JSVar "_ps")) (JSObjectLiteral [])]   where-  jsDecls = (concat $ mapMaybe (\decl -> fmap (map $ optimize opts) $ declToJs opts name decl env) (decls))+  jsDecls = concat $ mapMaybe (\decl -> fmap (map $ optimize opts) $ declToJs opts name decl env) decls  -- | -- 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 (identToJs ident) (Just (valueToJs opts mp e val))+  Just [ JSVariableIntroduction (identToJs ident) (Just (valueToJs opts mp e val))          , setExportProperty ident (var ident) ] declToJs opts mp (BindingGroupDeclaration vals) e =   Just $ concatMap (\(ident, val) ->@@ -85,8 +83,8 @@         (JSBlock [JSReturn (go pn (index + 1) tys' (JSVar ("value" ++ show index) : values))]) declToJs opts mp (DataBindingGroupDeclaration ds) e =   Just $ concat $ mapMaybe (flip (declToJs opts mp) e) ds-declToJs _ mp (ExternDeclaration importTy ident (Just js) _) _ =-  Just $ [js, setExportProperty ident (var ident)]+declToJs _ _ (ExternDeclaration _ ident (Just js) _) _ =+  Just [js, setExportProperty ident (var ident)] declToJs _ _ _ _ = Nothing  -- |@@ -94,7 +92,7 @@ -- declaration from a module. -- setExportProperty :: Ident -> JS -> JS-setExportProperty ident val = JSAssignment (accessor ident (JSVar "module")) val+setExportProperty ident = JSAssignment (accessor ident (JSVar "module"))  -- | -- Generate code in the simplified Javascript intermediate representation for a variable based on a@@ -194,12 +192,12 @@ varToJs :: ModuleName -> Environment -> Qualified Ident -> JS varToJs m e qual@(Qualified _ ident) = go qual   where-  go qual = case M.lookup (qualify m qual) (names e) of+  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+    _ -> case qual' of            Qualified Nothing _ -> var ident-           _ -> qualifiedToJS m id qual+           _ -> qualifiedToJS m id qual'   isExtern (Extern ForeignImport) = True   isExtern (Alias m' ident') = case M.lookup (m', ident') (names e) of     Just (_, ty') -> isExtern ty'@@ -212,7 +210,7 @@ -- qualifiedToJS :: ModuleName -> (a -> Ident) -> Qualified a -> JS qualifiedToJS m f (Qualified (Just m') a) | m /= m' = accessor (f a) (JSAccessor (moduleNameToJs m') $ JSVar "_ps")-qualifiedToJS m f (Qualified _ a) = JSVar $ identToJs (f a)+qualifiedToJS _ f (Qualified _ a) = JSVar $ identToJs (f a)  -- | -- Generate code in the simplified Javascript intermediate representation for pattern match binders@@ -256,7 +254,7 @@   return [JSIfElse (JSVar varName) (JSBlock done) Nothing] binderToJs _ _ varName done (BooleanBinder False) =   return [JSIfElse (JSUnary Not (JSVar varName)) (JSBlock done) Nothing]-binderToJs m e varName done (VarBinder ident) =+binderToJs _ _ varName done (VarBinder ident) =   return (JSVariableIntroduction (identToJs ident) (Just (JSVar varName)) : done) binderToJs m e varName done (ConstructorBinder ctor bs) = do   js <- go 0 done bs@@ -326,7 +324,7 @@   typeConstructor fn = error $ "Invalid arguments to typeConstructor: " ++ show fn  wrapExportsContainer :: Options -> [JS] -> JS-wrapExportsContainer opts modules = JSApp (JSFunction Nothing ["_ps"] $ JSBlock $ (JSStringLiteral "use strict") : modules) [exportSelector]+wrapExportsContainer opts modules = JSApp (JSFunction Nothing ["_ps"] $ JSBlock $ JSStringLiteral "use strict" : modules) [exportSelector]   where   exportSelector = JSConditional (JSBinary And (JSBinary NotEqualTo (JSTypeOf $ JSVar "module") (JSStringLiteral "undefined")) (JSAccessor "exports" (JSVar "module")))                            (JSAccessor "exports" (JSVar "module"))
src/Language/PureScript/CodeGen/Monad.hs view
@@ -21,7 +21,6 @@  import Control.Monad.State import Control.Applicative-import Language.PureScript.Names  -- | -- Code generation monad data type
src/Language/PureScript/CodeGen/Optimize.hs view
@@ -73,10 +73,10 @@ applyAll = foldl1 (.)  untilFixedPoint :: (Eq a) => (a -> a) -> a -> a-untilFixedPoint f a = go a+untilFixedPoint f = go   where-  go a' = let a'' = f a' in-          if a'' == a' then a'' else go a''+  go a = let a' = f a in+          if a' == a then a' else go a'  replaceIdent :: (Data d) => String -> JS -> d -> d replaceIdent var1 js = everywhere (mkT replace)@@ -100,7 +100,7 @@   check _ = False  isRebound :: (Data d) => JS -> d -> Bool-isRebound js d = any (\var -> isReassigned var d) (everything (++) (mkQ [] variablesOf) js)+isRebound js d = any (`isReassigned` d) (everything (++) (mkQ [] variablesOf) js)   where   variablesOf (JSVar var) = [var]   variablesOf _ = []@@ -135,25 +135,23 @@ shouldInline (JSIndexer index val) = shouldInline index && shouldInline val shouldInline _ = False +removeFromBlock :: ([JS] -> [JS]) -> JS -> JS+removeFromBlock go (JSBlock sts) = JSBlock (go sts)+removeFromBlock _  js = js+ inlineVariables :: JS -> JS-inlineVariables = everywhere (mkT removeFromBlock)+inlineVariables = everywhere (mkT $ removeFromBlock go)   where-  removeFromBlock :: JS -> JS-  removeFromBlock (JSBlock sts) = JSBlock (go sts)-  removeFromBlock js = js   go :: [JS] -> [JS]   go [] = []-  go (s@(JSVariableIntroduction var (Just js)) : sts)+  go (JSVariableIntroduction var (Just js) : sts)     | shouldInline js && not (isReassigned var sts) && not (isRebound js sts) && not (isUpdated var sts) =       go (replaceIdent var js sts)   go (s:sts) = s : go sts  removeUnusedVariables :: JS -> JS-removeUnusedVariables = everywhere (mkT removeFromBlock)+removeUnusedVariables = everywhere (mkT $ removeFromBlock go)   where-  removeFromBlock :: JS -> JS-  removeFromBlock (JSBlock sts) = JSBlock (go sts)-  removeFromBlock js = js   go :: [JS] -> [JS]   go [] = []   go (JSVariableIntroduction var _ : sts) | not (isUsed var sts) = go sts@@ -165,8 +163,8 @@   convert :: JS -> JS   convert (JSBlock [JSReturn (JSApp (JSFunction Nothing idents block@(JSBlock body)) args)])     | all shouldInline args &&-      not (any (flip isRebound block) (map JSVar idents)) &&-      not (or (map (flip isRebound block) args))+      not (any (`isRebound` block) (map JSVar idents)) &&+      not (any (`isRebound` block) args)       = JSBlock (replaceIdents (zip idents args) body)   convert js = js @@ -191,7 +189,7 @@   copyVar :: String -> String   copyVar arg = "__copy_" ++ arg   convert :: JS -> JS-  convert js@(JSVariableIntroduction name (Just fn@(JSFunction _ _ _))) =+  convert js@(JSVariableIntroduction name (Just fn@JSFunction {})) =     let       (argss, body', replace) = collectAllFunctionArgs [] id fn     in case () of@@ -206,11 +204,11 @@   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 _)) =-    (args : allArgs, body, \b -> f (JSFunction ident (map copyVar args) b))+    (args : allArgs, body, f . JSFunction ident (map copyVar args))   collectAllFunctionArgs allArgs f (JSReturn (JSFunction ident args (JSBlock [body]))) =     collectAllFunctionArgs (args : allArgs) (\b -> f (JSReturn (JSFunction ident (map copyVar args) (JSBlock [b])))) body   collectAllFunctionArgs allArgs f (JSReturn (JSFunction ident args body@(JSBlock _))) =-    (args : allArgs, body, \b -> f (JSReturn (JSFunction ident (map copyVar args) b)))+    (args : allArgs, body, f . JSReturn . JSFunction ident (map copyVar args))   collectAllFunctionArgs allArgs f body = (allArgs, body, f)   isTailCall :: String -> JS -> Bool   isTailCall ident js =@@ -312,19 +310,19 @@   isRetPoly (JSIndexer (JSStringLiteral "return") (JSAccessor "Prelude" (JSVar "_ps"))) = True   isRetPoly _ = False   -- Check if an expression represents a function in the Ef module-  isEffFunc name (JSAccessor name' (JSAccessor "Eff" (JSVar "_ps"))) | name == name' = True+  isEffFunc name (JSAccessor name' (JSAccessor "Control_Monad_Eff" (JSVar "_ps"))) | name == name' = True   isEffFunc _ _ = False   -- Module names   prelude = ModuleName [ProperName "Prelude"]-  effModule = ModuleName [ProperName "Eff"]+  effModule = ModuleName [ProperName "Control", ProperName "Monad", ProperName "Eff"]   -- The name of the type class dictionary for the Monad Eff instance   Right (Ident effDictName) = mkDictionaryValueName     effModule     (Qualified (Just prelude) (ProperName "Monad"))-    (TypeConstructor (Qualified (Just effModule) (ProperName "Eff")))+    [TypeConstructor (Qualified (Just effModule) (ProperName "Eff"))]   -- Check if an expression represents the Monad Eff dictionary   isEffDict (JSApp (JSVar ident) [JSObjectLiteral []]) | ident == effDictName = True-  isEffDict (JSApp (JSAccessor prop (JSAccessor "Eff" (JSVar "_ps"))) [JSObjectLiteral []]) | prop == effDictName = True+  isEffDict (JSApp (JSAccessor prop (JSAccessor "Control_Monad_Eff" (JSVar "_ps"))) [JSObjectLiteral []]) | prop == effDictName = True   isEffDict _ = False   -- Remove __do function applications which remain after desugaring   undo :: JS -> JS@@ -345,7 +343,7 @@         usages = findAllSTUsagesIn arg         allUsagesAreLocalVars = all (\u -> let v = toVar u in isJust v && fromJust v `elem` refs) usages         localVarsDoNotEscape = all (\r -> length (r `appearingIn` arg) == length (filter (\u -> let v = toVar u in v == Just r) usages)) refs-    in everywhere (mkT $ convert allUsagesAreLocalVars) arg+    in everywhere (mkT $ convert (allUsagesAreLocalVars && localVarsDoNotEscape)) arg   convertBlock other = other   -- Convert a block in a safe way, preserving object wrappers of references,   -- or in a more aggressive way, turning wrappers into local variables depending on the@@ -359,17 +357,17 @@   convert agg (JSApp (JSApp (JSApp f [ref]) [func]) []) | isSTFunc "modifySTRef" f =     if agg then JSAssignment ref (JSApp func [ref]) else  JSAssignment (JSAccessor "value" ref) (JSApp func [JSAccessor "value" ref])   convert _ (JSApp (JSApp (JSApp f [arr]) [i]) []) | isSTFunc "peekSTArray" f =-    (JSIndexer i arr)+    JSIndexer i arr   convert _ (JSApp (JSApp (JSApp (JSApp f [arr]) [i]) [val]) []) | isSTFunc "pokeSTArray" f =     JSAssignment (JSIndexer i arr) val   convert _ other = other   -- Check if an expression represents a function in the ST module-  isSTFunc name (JSAccessor name' (JSAccessor "ST" (JSVar "_ps"))) | name == name' = True+  isSTFunc name (JSAccessor name' (JSAccessor "Control_Monad_ST" (JSVar "_ps"))) | name == name' = True   isSTFunc _ _ = False   -- Find all ST Refs initialized in this block   findSTRefsIn = everything (++) (mkQ [] isSTRef)     where-    isSTRef (JSVariableIntroduction ident (Just (JSApp (JSApp f [arg]) []))) | isSTFunc "newSTRef" f = [ident]+    isSTRef (JSVariableIntroduction ident (Just (JSApp (JSApp f [_]) []))) | isSTFunc "newSTRef" f = [ident]     isSTRef _ = []   -- Find all STRefs used as arguments to readSTRef, writeSTRef, modifySTRef   findAllSTUsagesIn = everything (++) (mkQ [] isSTUsage)@@ -400,7 +398,7 @@ inlineOperator op f = everywhere (mkT convert)   where   convert :: JS -> JS-  convert (JSApp (JSApp op [x]) [y]) | isOp op = f x y+  convert (JSApp (JSApp op' [x]) [y]) | isOp op' = f x y   convert other = other   isOp (JSAccessor longForm (JSAccessor "Prelude" (JSVar "_ps"))) | longForm == identToJs (Op op) = True   isOp (JSIndexer (JSStringLiteral op') (JSAccessor "Prelude" (JSVar "_ps"))) | op == op' = True@@ -446,7 +444,7 @@     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 (JSAccessor "Prelude" (JSVar ps))) | longForm == identToJs (Op opString) = True+    isOp (JSAccessor longForm (JSAccessor "Prelude" (JSVar _))) | longForm == identToJs (Op opString) = True     isOp (JSIndexer (JSStringLiteral op') (JSAccessor "Prelude" (JSVar "_ps"))) | opString == op' = True     isOp _ = False   binaryFunction :: String -> String -> Type -> BinaryOperator -> JS -> JS@@ -470,5 +468,5 @@     Right (Ident dictName) = mkDictionaryValueName       (ModuleName [ProperName "Prim"])       (Qualified (Just (ModuleName [ProperName "Prelude"])) (ProperName className))-      ty+      [ty]   isOpDict _ _ _ = False
src/Language/PureScript/DeadCodeElimination.hs view
@@ -35,19 +35,19 @@   let declarations = concatMap (declarationsByModule env) ms       (graph, _, vertexFor) = graphFromEdges $ map (\(key, deps) -> (key, key, deps)) declarations       entryPointVertices = mapMaybe (vertexFor . fst) . filter (\((mn, _), _) -> mn `elem` entryPoints) $ declarations-  in flip map ms $ \(Module moduleName ds) -> Module moduleName (filter (isUsed (moduleName) graph vertexFor entryPointVertices) ds)+  in flip map ms $ \(Module moduleName ds) -> Module moduleName (filter (isUsed moduleName graph vertexFor entryPointVertices) ds)  type Key = (ModuleName, Either Ident ProperName)  declarationsByModule :: Environment -> Module -> [(Key, [Key])]-declarationsByModule env (Module moduleName ds) = concatMap go $ ds+declarationsByModule env (Module moduleName ds) = concatMap go ds   where   go :: Declaration -> [(Key, [Key])]-  go d@(ValueDeclaration name _ _ _) = [((moduleName, Left name), dependencies env (moduleName) d)]+  go d@(ValueDeclaration name _ _ _) = [((moduleName, Left name), dependencies env moduleName d)]   go (DataDeclaration _ _ dctors) = map (\(name, _) -> ((moduleName, Right name), [])) dctors   go (ExternDeclaration _ name _ _) = [((moduleName, Left name), [])]-  go d@(BindingGroupDeclaration names) = map (\(name, _) -> ((moduleName, Left name), dependencies env moduleName d)) names-  go (DataBindingGroupDeclaration ds) = concatMap go ds+  go d@(BindingGroupDeclaration names') = map (\(name, _) -> ((moduleName, Left name), dependencies env moduleName d)) names'+  go (DataBindingGroupDeclaration ds') = concatMap go ds'   go _ = []  dependencies :: (Data d) => Environment -> ModuleName -> d -> [Key]
src/Language/PureScript/Declarations.hs view
@@ -112,60 +112,60 @@   -- |   -- A type class declaration (name, argument, member declarations)   ---  | TypeClassDeclaration ProperName String [Declaration]+  | TypeClassDeclaration ProperName [String] [Declaration]   -- |   -- A type instance declaration (dependencies, class name, instance type, member declarations)   ---  | TypeInstanceDeclaration [(Qualified ProperName, Type)] (Qualified ProperName) Type [Declaration]+  | TypeInstanceDeclaration [(Qualified ProperName, [Type])] (Qualified ProperName) [Type] [Declaration]   deriving (Show, D.Data, D.Typeable)  -- | -- Test if a declaration is a value declaration -- isValueDecl :: Declaration -> Bool-isValueDecl (ValueDeclaration _ _ _ _) = True+isValueDecl ValueDeclaration{} = True isValueDecl _ = False  -- | -- Test if a declaration is a data type or type synonym declaration -- isDataDecl :: Declaration -> Bool-isDataDecl (DataDeclaration _ _ _) = True-isDataDecl (TypeSynonymDeclaration _ _ _) = True+isDataDecl DataDeclaration{} = True+isDataDecl TypeSynonymDeclaration{} = True isDataDecl _ = False  -- | -- Test if a declaration is a module import -- isImportDecl :: Declaration -> Bool-isImportDecl (ImportDeclaration _ _) = True+isImportDecl ImportDeclaration{} = True isImportDecl _ = False  -- | -- Test if a declaration is a data type foreign import -- isExternDataDecl :: Declaration -> Bool-isExternDataDecl (ExternDataDeclaration _ _) = True+isExternDataDecl ExternDataDeclaration{} = True isExternDataDecl _ = False  -- | -- Test if a declaration is a fixity declaration -- isFixityDecl :: Declaration -> Bool-isFixityDecl (FixityDeclaration _ _) = True+isFixityDecl FixityDeclaration{} = True isFixityDecl _ = False  -- | -- Test if a declaration is a foreign import -- isExternDecl :: Declaration -> Bool-isExternDecl (ExternDeclaration _ _ _ _) = True+isExternDecl ExternDeclaration{} = True isExternDecl _ = False  -- | -- Test if a declaration is a type class or instance declaration -- isTypeClassDeclaration :: Declaration -> Bool-isTypeClassDeclaration (TypeClassDeclaration _ _ _) = True-isTypeClassDeclaration (TypeInstanceDeclaration _ _ _ _) = True+isTypeClassDeclaration TypeClassDeclaration{} = True+isTypeClassDeclaration TypeInstanceDeclaration{} = True isTypeClassDeclaration _ = False
src/Language/PureScript/ModuleDependencies.hs view
@@ -19,13 +19,10 @@ import Data.Data import Data.Graph import Data.Generics-import Data.List (nub, intersect)-import Control.Applicative ((<$>))+import Data.List (nub)  import Language.PureScript.Declarations import Language.PureScript.Names-import Language.PureScript.Values-import Language.PureScript.Types  -- | -- Sort a collection of modules based on module dependencies.
src/Language/PureScript/Names.hs view
@@ -70,6 +70,14 @@ runModuleName :: ModuleName -> String runModuleName (ModuleName pns) = intercalate "." (runProperName `map` pns) +moduleNameFromString :: String -> ModuleName+moduleNameFromString = ModuleName . splitProperNames+  where+  splitProperNames s = case dropWhile (== '.') s of+    "" -> []+    s' -> ProperName w : splitProperNames s''+      where (w, s'') = break (== '.') s'+ instance Show ModuleName where   show = runModuleName 
src/Language/PureScript/Options.hs view
@@ -33,7 +33,7 @@   , optionsMagicDo :: Bool     -- |     -- When specified, checks the type of `main` in the module, and generate a call to run main-    -- after the module definitions. +    -- after the module definitions.     --   , optionsMain :: Maybe String     -- |
src/Language/PureScript/Parser/Common.hs view
@@ -48,8 +48,8 @@                   , "let"                   , "true"                   , "false"-                  , "until"                   , "in"+                  , "where"                   ]  -- |@@ -328,7 +328,7 @@ -- Parse an identifier in backticks or an operator -- parseIdentInfix :: P.Parsec String ParseState (Qualified Ident)-parseIdentInfix = (P.between tick tick (parseQualified (Ident <$> identifier))) <|> Qualified Nothing <$> (Op <$> operator)+parseIdentInfix = P.between tick tick (parseQualified (Ident <$> identifier)) <|> Qualified Nothing <$> (Op <$> operator)  -- | -- Mark the current indentation level
src/Language/PureScript/Parser/Declarations.hs view
@@ -20,11 +20,9 @@ ) where  import Data.Maybe (isJust, fromMaybe)-import Control.Monad (when) import Control.Applicative import qualified Text.Parsec as P -import Language.PureScript.Names import Language.PureScript.Parser.State import Language.PureScript.Parser.Common import Language.PureScript.Declarations@@ -32,7 +30,6 @@ import Language.PureScript.Parser.Types import Language.PureScript.Parser.Kinds import Language.PureScript.CodeGen.JS.AST-import Language.PureScript.Values  parseDataDeclaration :: P.Parsec String ParseState Declaration parseDataDeclaration = do@@ -59,15 +56,15 @@   ValueDeclaration <$> parseIdent                    <*> P.many parseBinderNoParens                    <*> P.optionMaybe parseGuard-                   <*> ((lexeme (indented *> P.char '=')) *> parseValue)+                   <*> (lexeme (indented *> P.char '=') *> parseValue)  parseExternDeclaration :: P.Parsec String ParseState Declaration-parseExternDeclaration = P.try (reserved "foreign") *> indented *> (reserved "import") *> indented *>+parseExternDeclaration = P.try (reserved "foreign") *> indented *> reserved "import" *> indented *>    (ExternDataDeclaration <$> (P.try (reserved "data") *> indented *> properName)                              <*> (lexeme (indented *> P.string "::") *> parseKind)    <|> do ident <- parseIdent           js <- P.optionMaybe (JSRaw <$> stringLiteral)-          ty <- (lexeme (indented *> P.string "::") *> parsePolyType)+          ty <- lexeme (indented *> P.string "::") *> parsePolyType           return $ ExternDeclaration (if isJust js then InlineJavascript else ForeignImport) ident js ty)  parseAssociativity :: P.Parsec String ParseState Associativity@@ -89,29 +86,29 @@ parseImportDeclaration = do   reserved "import"   indented-  moduleName <- moduleName+  moduleName' <- moduleName   idents <- P.optionMaybe $ parens $ commaSep1 (Left <$> parseIdent <|> Right <$> properName)-  return $ ImportDeclaration moduleName idents+  return $ ImportDeclaration moduleName' idents  parseTypeClassDeclaration :: P.Parsec String ParseState Declaration parseTypeClassDeclaration = do   reserved "class"   className <- indented *> properName-  ident <- indented *> identifier+  idents <- indented *> P.many identifier   indented *> reserved "where"   members <- mark (P.many (same *> parseTypeDeclaration))-  return $ TypeClassDeclaration className ident members+  return $ TypeClassDeclaration className idents members  parseTypeInstanceDeclaration :: P.Parsec String ParseState Declaration parseTypeInstanceDeclaration = do   reserved "instance"   deps <- P.optionMaybe $ do-    deps <- parens (commaSep1 ((,) <$> parseQualified properName <*> parseType))+    deps <- parens (commaSep1 ((,) <$> parseQualified properName <*> P.many parseTypeAtom))     indented     reservedOp "=>"     return deps   className <- indented *> parseQualified properName-  ty <- indented *> parseType+  ty <- indented *> P.many parseTypeAtom   indented *> reserved "where"   members <- mark (P.many (same *> parseValueDeclaration))   return $ TypeInstanceDeclaration (fromMaybe [] deps) className ty members
src/Language/PureScript/Parser/Types.hs view
@@ -51,15 +51,15 @@ parseTypeVariable :: P.Parsec String ParseState Type parseTypeVariable = do   ident <- identifier-  when (ident `elem` reservedTypeNames) $ P.unexpected $ ident+  when (ident `elem` reservedTypeNames) $ P.unexpected ident   return $ TypeVar ident  parseTypeConstructor :: P.Parsec String ParseState Type parseTypeConstructor = TypeConstructor <$> parseQualified properName  parseForAll :: P.Parsec String ParseState Type-parseForAll = (mkForAll <$> (P.try (reserved "forall") *> P.many1 (indented *> identifier) <* indented <* dot)-                        <*> parseConstrainedType)+parseForAll = mkForAll <$> (P.try (reserved "forall") *> P.many1 (indented *> identifier) <* indented <* dot)+                       <*> parseConstrainedType  -- | -- Parse a type as it appears in e.g. a data constructor@@ -85,7 +85,7 @@     constraints <- parens . commaSep1 $ do       className <- parseQualified properName       indented-      ty <- parseType+      ty <- P.many parseTypeAtom       return (className, ty)     _ <- lexeme $ P.string "=>"     return constraints@@ -94,7 +94,7 @@   return $ maybe ty (flip ConstrainedType ty) constraints  parseAnyType :: P.Parsec String ParseState Type-parseAnyType = (P.buildExpressionParser operators $ parseTypeAtom) P.<?> "type"+parseAnyType = P.buildExpressionParser operators parseTypeAtom P.<?> "type"   where   operators = [ [ P.Infix (return TypeApp) P.AssocLeft ]               , [ P.Infix (P.try (lexeme (P.string "->")) >> return function) P.AssocRight ] ]@@ -112,9 +112,7 @@ -- Parse a polytype -- parsePolyType :: P.Parsec String ParseState Type-parsePolyType = do-  ty <- parseAnyType-  return ty+parsePolyType = parseAnyType  parseNameAndType :: P.Parsec String ParseState t -> P.Parsec String ParseState (String, t) parseNameAndType p = (,) <$> (indented *> identifier <* indented <* lexeme (P.string "::")) <*> p@@ -123,5 +121,5 @@ parseRowEnding = P.option REmpty (TypeVar <$> (lexeme (indented *> P.char '|') *> indented *> identifier))  parseRow :: Bool -> P.Parsec String ParseState Type-parseRow nonEmpty = (curry rowFromList <$> (many $ parseNameAndType parsePolyType) <*> parseRowEnding) P.<?> "row"-  where many = if nonEmpty then commaSep1 else commaSep+parseRow nonEmpty = (curry rowFromList <$> many' (parseNameAndType parsePolyType) <*> parseRowEnding) P.<?> "row"+  where many' = if nonEmpty then commaSep1 else commaSep
src/Language/PureScript/Parser/Values.hs view
@@ -20,13 +20,16 @@     parseBinderNoParens, ) where +import Control.Applicative+ import Language.PureScript.Values import Language.PureScript.Parser.State+import Language.PureScript.Parser.Types++import Text.Parsec.Expr+ import qualified Language.PureScript.Parser.Common as C-import Control.Applicative import qualified Text.Parsec as P-import Text.Parsec.Expr-import Language.PureScript.Parser.Types  booleanLiteral :: P.Parsec String ParseState Bool booleanLiteral = (C.reserved "true" >> return True) P.<|> (C.reserved "false" >> return False)@@ -59,7 +62,7 @@   return $ toFunction args value   where   toFunction :: [Value -> Value] -> Value -> Value-  toFunction args value = foldr (($)) value args+  toFunction args value = foldr ($) value args  parseVar :: P.Parsec String ParseState Value parseVar = Var <$> C.parseQualified C.parseIdent@@ -154,7 +157,7 @@   indexersAndAccessors = C.buildPostfixParser postfixTable1 parseValueAtom   postfixTable1 = [ parseAccessor                   , \v -> P.try $ flip ObjectUpdate <$> (C.indented *> C.braces (C.commaSep1 (C.indented *> parsePropertyUpdate))) <*> pure v ]-  postfixTable2 = [ \v -> P.try (C.indented *> indexersAndAccessors >>= return . flip App) <*> pure v+  postfixTable2 = [ \v -> P.try (flip App <$> (C.indented *> indexersAndAccessors)) <*> pure v                   , \v -> flip (TypedValue True) <$> (P.try (C.lexeme (C.indented *> P.string "::")) *> parsePolyType) <*> pure v                   ]   operators = [ [ Infix (C.lexeme (P.try (C.indented *> C.parseIdentInfix P.<?> "operator") >>= \ident ->@@ -177,13 +180,13 @@ parseNullaryConstructorBinder = ConstructorBinder <$> C.lexeme (C.parseQualified C.properName) <*> pure []  parseConstructorBinder :: P.Parsec String ParseState Binder-parseConstructorBinder = ConstructorBinder <$> C.lexeme (C.parseQualified C.properName) <*> (many (C.indented *> parseBinderNoParens))+parseConstructorBinder = ConstructorBinder <$> C.lexeme (C.parseQualified C.properName) <*> many (C.indented *> parseBinderNoParens)  parseObjectBinder :: P.Parsec String ParseState Binder parseObjectBinder = ObjectBinder <$> C.braces (C.commaSep (C.indented *> parseIdentifierAndBinder))  parseArrayBinder :: P.Parsec String ParseState Binder-parseArrayBinder = C.squares $ ArrayBinder <$> (C.commaSep (C.indented *> parseBinder))+parseArrayBinder = C.squares $ ArrayBinder <$> C.commaSep (C.indented *> parseBinder)  parseNamedBinder :: P.Parsec String ParseState Binder parseNamedBinder = NamedBinder <$> (C.parseIdent <* C.indented <* C.lexeme (P.char '@'))@@ -203,7 +206,7 @@ -- Parse a binder -- parseBinder :: P.Parsec String ParseState Binder-parseBinder = (buildExpressionParser operators parseBinderAtom) P.<?> "expression"+parseBinder = buildExpressionParser operators parseBinderAtom P.<?> "expression"   where   operators = [ [ Infix ( C.lexeme (P.try $ C.indented *> C.reservedOp ":") >> return ConsBinder) AssocRight ] ]   parseBinderAtom :: P.Parsec String ParseState Binder
src/Language/PureScript/Pretty/JS.hs view
@@ -17,8 +17,6 @@     prettyPrintJS ) where -import Language.PureScript.Names-import Language.PureScript.Values import Language.PureScript.Pretty.Common import Language.PureScript.CodeGen.JS.AST @@ -69,7 +67,7 @@     , fmap (intercalate ", ") $ forM xs prettyPrintJS'     , return " ]"     ]-  match (JSObjectLiteral []) = return "{}" +  match (JSObjectLiteral []) = return "{}"   match (JSObjectLiteral ps) = fmap concat $ sequence     [ return "{\n"     , withIndent $ do@@ -82,10 +80,7 @@     ]   match (JSBlock sts) = fmap concat $ sequence     [ return "{\n"-    , withIndent $ do-        jss <- forM sts prettyPrintJS'-        indentString <- currentIndent-        return $ intercalate "\n" $ map (++ ";") $ map (indentString ++) jss+    , withIndent $ prettyStatements sts     , return "\n"     , currentIndent     , return "}"@@ -195,6 +190,12 @@     match' (JSBinary op' v1 v2) | op' == op = Just (v1, v2)     match' _ = Nothing +prettyStatements :: [JS] -> StateT PrinterState Maybe String+prettyStatements sts = do+  jss <- forM sts prettyPrintJS'+  indentString <- currentIndent+  return $ intercalate "\n" $ map ((++ ";") . (indentString ++)) jss+ -- | -- Generate a pretty-printed string representing a Javascript expression --@@ -205,10 +206,7 @@ -- Generate a pretty-printed string representing a collection of Javascript expressions at the same indentation level -- prettyPrintJS :: [JS] -> String-prettyPrintJS sts = fromMaybe (error "Incomplete pattern") . flip evalStateT (PrinterState 0) $ do-  jss <- forM sts prettyPrintJS'-  indentString <- currentIndent-  return $ intercalate "\n" $ map (++ ";") $ map (indentString ++) jss+prettyPrintJS = fromMaybe (error "Incomplete pattern") . flip evalStateT (PrinterState 0) . prettyStatements  -- | -- Generate an indented, pretty-printed string representing a Javascript expression@@ -224,8 +222,8 @@                   , [ Wrap indexer $ \index val -> val ++ "[" ++ index ++ "]" ]                   , [ Wrap app $ \args val -> val ++ "(" ++ args ++ ")" ]                   , [ Wrap lam $ \(name, args) ret -> "function "-                        ++ maybe "" id name-                        ++ "(" ++ (intercalate ", " args) ++ ") "+                        ++ fromMaybe "" name+                        ++ "(" ++ intercalate ", " args ++ ") "                         ++ ret ]                   , [ Wrap conditional $ \(th, el) cond -> cond ++ " ? " ++ prettyPrintJS1 th ++ " : " ++ prettyPrintJS1 el ]                   , [ binary    LessThan             "<" ]
src/Language/PureScript/Pretty/Types.hs view
@@ -35,14 +35,14 @@   match (Object row) = Just $ "{ " ++ prettyPrintRow row ++ " }"   match (TypeVar var) = Just var   match (PrettyPrintArray ty) = Just $ "[" ++ prettyPrintType ty ++ "]"-  match ty@(TypeConstructor ctor) = Just $ show ctor+  match (TypeConstructor ctor) = Just $ show ctor   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 (ConstrainedType deps ty) = Just $ "(" ++ intercalate "," (map (\(pn, ty') -> show pn ++ " (" ++ unwords (map prettyPrintType ty') ++ ")") deps) ++ ") => " ++ prettyPrintType ty   match (SaturatedTypeSynonym name args) = Just $ show name ++ "<" ++ intercalate "," (map prettyPrintType args) ++ ">"   match (ForAll ident ty _) = Just $ "forall " ++ ident ++ ". " ++ prettyPrintType ty   match REmpty = Just "()"-  match row@(RCons _ _ _) = Just $ '(' : prettyPrintRow row ++ ")"+  match row@RCons{} = Just $ '(' : prettyPrintRow row ++ ")"   match _ = Nothing  -- |
src/Language/PureScript/Pretty/Values.hs view
@@ -38,7 +38,7 @@   match (ArrayLiteral xs) = Just $ "[" ++ intercalate ", " (map prettyPrintValue xs) ++ "]"   match (ObjectLiteral ps) = Just $ "{" ++ intercalate ", " (map (uncurry prettyPrintObjectProperty) ps) ++ "}"   match (Constructor name) = Just $ show name-  match (Case values binders) = Just $ "case " ++ intercalate " " (map prettyPrintValue values) +++  match (Case values binders) = Just $ "case " ++ unwords (map prettyPrintValue values) ++     " of { " ++ intercalate " ; " (map prettyPrintCaseAlternative binders) ++ " }"   match (Var ident) = Just $ show ident   match (Do els) = Just $ " do { " ++ intercalate "; " (map prettyPrintDoNotationElement els) ++ " }"@@ -47,7 +47,7 @@  prettyPrintCaseAlternative :: ([Binder], Maybe Guard, Value) -> String prettyPrintCaseAlternative (binders, grd, val) = "(" ++ intercalate ", " (map prettyPrintBinder binders) ++ ") " ++-  (maybe "" (("| " ++) . prettyPrintValue) grd) ++ " -> " ++ prettyPrintValue val+  maybe "" (("| " ++) . prettyPrintValue) grd ++ " -> " ++ prettyPrintValue val  ifThenElse :: Pattern () Value ((Value, Value), Value) ifThenElse = mkPattern match@@ -118,7 +118,7 @@   match (BooleanBinder True) = Just "true"   match (BooleanBinder False) = Just "false"   match (VarBinder ident) = Just $ show ident-  match (ConstructorBinder ctor args) = Just $ show ctor ++ " " ++ intercalate " " (map (parens . prettyPrintBinder) args)+  match (ConstructorBinder ctor args) = Just $ show ctor ++ " " ++ unwords (map (parens . prettyPrintBinder) args)   match (ObjectBinder bs) = Just $ "{ " ++ intercalate ", " (map (uncurry prettyPrintObjectPropertyBinder) bs) ++ " }"   match (ArrayBinder bs) = Just $ "[ " ++ intercalate ", " (map prettyPrintBinder bs) ++ " ]"   match (NamedBinder ident binder) = Just $ show ident ++ "@" ++ prettyPrintBinder binder
src/Language/PureScript/Scope.hs view
@@ -18,6 +18,8 @@     unusedNames ) where +import Control.Applicative ((<$>))+ import Data.Data import Data.List ((\\), nub) import Data.Generics (extQ, mkQ, everything)@@ -41,8 +43,8 @@   namesB _ = []   namesJS :: JS -> [Ident]   namesJS (JSVar name) = [Ident name]-  namesJS (JSFunction (Just name) args _) = (Ident name) : (Ident `map` args)-  namesJS (JSFunction Nothing args _) = (Ident `map` args)+  namesJS (JSFunction (Just name) args _) = Ident name : (Ident <$> args)+  namesJS (JSFunction Nothing args _) = Ident <$> args   namesJS (JSVariableIntroduction name _) = [Ident name]   namesJS (JSFor name _ _ _) = [Ident name]   namesJS _ = []
src/Language/PureScript/Sugar/BindingGroups.hs view
@@ -69,7 +69,7 @@ -- Collapse all binding groups to individual declarations -- collapseBindingGroups :: [Declaration] -> [Declaration]-collapseBindingGroups ds = concatMap go ds+collapseBindingGroups = concatMap go   where   go (DataBindingGroupDeclaration ds) = ds   go (BindingGroupDeclaration ds) = map (\(ident, val) -> ValueDeclaration ident [] Nothing val) ds@@ -112,10 +112,10 @@   | all isTypeSynonym ds' = Left "Cycle in type synonyms"   | otherwise = return $ DataBindingGroupDeclaration ds'   where-  isTypeSynonym (TypeSynonymDeclaration _ _ _) = True+  isTypeSynonym TypeSynonymDeclaration{} = True   isTypeSynonym _ = False  fromValueDecl :: Declaration -> (Ident, Value) fromValueDecl (ValueDeclaration ident [] Nothing val) = (ident, val)-fromValueDecl (ValueDeclaration _ _ _ _) = error "Binders should have been desugared"+fromValueDecl ValueDeclaration{} = error "Binders should have been desugared" fromValueDecl _ = error "Expected ValueDeclaration"
src/Language/PureScript/Sugar/CaseDeclarations.hs view
@@ -75,7 +75,7 @@   let     argPattern = length . fst . head $ alternatives     args = take argPattern $ unusedNames (ident, alternatives)-    vars = map (\arg -> Var (Qualified Nothing arg)) args+    vars = map (Var . Qualified Nothing) args     binders = [ (bs, g, val) | (bs, (g, val)) <- alternatives ]     value = foldr (\arg ret -> Abs (Left arg) ret) (Case vars binders) args   in
src/Language/PureScript/Sugar/Operators.hs view
@@ -27,13 +27,17 @@ import Language.PureScript.Declarations import Language.PureScript.Values +import Control.Applicative+import Control.Arrow (first)+import Control.Monad.State+ import Data.Function (on) import Data.List (groupBy, sortBy)+ import qualified Data.Map as M import qualified Data.Generics as G import qualified Data.Generics.Extras as G-import Control.Monad.State-import Control.Applicative+ import qualified Text.Parsec as P import qualified Text.Parsec.Pos as P import qualified Text.Parsec.Expr as P@@ -62,9 +66,9 @@     -- The fixity map can therefore map from module name/ident pairs to fixities, where the module name is the name     -- of the module imported into, not from. This is useful in matchOp, but here we have to discard the module name to     -- make sure that the generated code is correct.-    applyUserOp (Qualified _ name) t1 t2 = App (App (Var (Qualified Nothing name)) t1) t2+    applyUserOp (Qualified _ name) t1 = App (App (Var (Qualified Nothing name)) t1)     userOps = map (\(name, Fixity a p) -> (name, applyUserOp name, p, a)) . M.toList $ fixities-    sorted = reverse $ sortBy (compare `on` (\(_, _, p, _) -> p)) userOps+    sorted = sortBy (flip compare `on` (\(_, _, p, _) -> p)) userOps     groups = groupBy ((==) `on` (\(_, _, p, _) -> p)) sorted   in     map (map (\(name, f, _, a) -> (name, f, a))) groups@@ -72,10 +76,10 @@ type Chain = [Either Value (Qualified Ident)]  matchOperators :: ModuleName -> [[(Qualified Ident, Value -> Value -> Value, Associativity)]] -> Value -> Either String Value-matchOperators moduleName ops val = G.everywhereM' (G.mkM parseChains) val+matchOperators moduleName ops = G.everywhereM' (G.mkM parseChains)   where   parseChains :: Value -> Either String Value-  parseChains b@(BinaryNoParens _ _ _) = bracketChain (extendChain b)+  parseChains b@BinaryNoParens{} = bracketChain (extendChain b)   parseChains other = return other   extendChain :: Value -> Chain   extendChain (BinaryNoParens name l r) = Left l : Right name : extendChain r@@ -108,7 +112,7 @@   collectFixities (M.insert qual fixity m) moduleName rest collectFixities m moduleName (ImportDeclaration importedModule _ : rest) = do   let fs = [ (i, fixity) | (Qualified mn i, fixity) <- M.toList m, mn == Just importedModule ]-  let m' = M.fromList (map (\(i, fixity) -> (Qualified (Just moduleName) i, fixity)) fs)-  collectFixities (M.union m' m) moduleName rest+  let m' = M.fromList (map (first (Qualified (Just moduleName))) fs)+  collectFixities (m' `M.union` m) moduleName rest collectFixities m moduleName (_:ds) = collectFixities m moduleName ds 
src/Language/PureScript/Sugar/TypeClasses.hs view
@@ -31,14 +31,12 @@  import Control.Applicative import Control.Monad.State-import Control.Arrow ((***))+import Control.Arrow (second) -import Data.Maybe (fromMaybe)-import Data.List (nub)-import Data.Generics (mkQ, everything)+import Data.List (intercalate) import Language.PureScript.CodeGen.Common (identToJs, moduleNameToJs) -type MemberMap = M.Map (ModuleName, ProperName) (String, [(String, Type)])+type MemberMap = M.Map (ModuleName, ProperName) ([String], [(String, Type)])  type Desugar = StateT MemberMap (Either String) @@ -91,10 +89,10 @@ --   __Test_Foo_array _1 = { foo: __Test_Foo_array_foo _1 :: [a] -> [a] (unchecked) } -- desugarDecl :: ModuleName -> Declaration -> Desugar [Declaration]-desugarDecl mn d@(TypeClassDeclaration name arg members) = do+desugarDecl mn d@(TypeClassDeclaration name args members) = do   let tys = map memberToNameAndType members-  modify (M.insert (mn, name) (arg, tys))-  return $ d : typeClassDictionaryDeclaration name arg members : map (typeClassMemberToDictionaryAccessor name arg) members+  modify (M.insert (mn, name) (args, tys))+  return $ d : typeClassDictionaryDeclaration name args members : map (typeClassMemberToDictionaryAccessor name args) members desugarDecl mn d@(TypeInstanceDeclaration deps name ty members) = do   desugared <- lift $ desugarCases members   entries <- mapM (typeInstanceDictionaryEntryDeclaration mn deps name ty) desugared@@ -106,50 +104,50 @@ memberToNameAndType (TypeDeclaration ident ty) = (identToJs ident, ty) memberToNameAndType _ = error "Invalid declaration in type class definition" -typeClassDictionaryDeclaration :: ProperName -> String -> [Declaration] -> Declaration-typeClassDictionaryDeclaration name arg members =-  TypeSynonymDeclaration name [arg] (Object $ rowFromList (map memberToNameAndType members, REmpty))+typeClassDictionaryDeclaration :: ProperName -> [String] -> [Declaration] -> Declaration+typeClassDictionaryDeclaration name args members =+  TypeSynonymDeclaration name args (Object $ rowFromList (map memberToNameAndType members, REmpty)) -typeClassMemberToDictionaryAccessor :: ProperName -> String -> Declaration -> Declaration-typeClassMemberToDictionaryAccessor name arg (TypeDeclaration ident ty) =+typeClassMemberToDictionaryAccessor :: ProperName -> [String] -> Declaration -> Declaration+typeClassMemberToDictionaryAccessor name args (TypeDeclaration ident ty) =   ExternDeclaration TypeClassAccessorImport ident     (Just (JSFunction (Just $ identToJs ident) ["dict"] (JSBlock [JSReturn (JSAccessor (identToJs ident) (JSVar "dict"))])))-    (ForAll arg (ConstrainedType [(Qualified Nothing name, TypeVar arg)] ty) Nothing)+    (quantify (ConstrainedType [(Qualified Nothing name, map TypeVar args)] ty)) typeClassMemberToDictionaryAccessor _ _ _ = error "Invalid declaration in type class definition" -typeInstanceDictionaryDeclaration :: ModuleName -> [(Qualified ProperName, Type)] -> Qualified ProperName -> Type -> [Declaration] -> Desugar Declaration-typeInstanceDictionaryDeclaration mn deps name ty decls = do+typeInstanceDictionaryDeclaration :: ModuleName -> [(Qualified ProperName, [Type])] -> Qualified ProperName -> [Type] -> [Declaration] -> Desugar Declaration+typeInstanceDictionaryDeclaration mn deps name tys decls = do   m <- get-  (arg, instanceTys) <- lift $ maybe (Left $ "Type class " ++ show name ++ " is undefined. Type class names must be qualified.") Right+  (args, instanceTys) <- lift $ maybe (Left $ "Type class " ++ show name ++ " is undefined. Type class names must be qualified.") Right                         $ M.lookup (qualify mn name) m-  let memberTypes = map (id *** replaceTypeVars arg ty) instanceTys-  entryName <- lift $ mkDictionaryValueName mn name ty+  let memberTypes = map (second (replaceAllTypeVars (zip args tys))) instanceTys+  entryName <- lift $ mkDictionaryValueName mn name tys   memberNames <- mapM (memberToNameAndValue memberTypes) decls   return $ ValueDeclaration entryName [] Nothing     (TypedValue True-      (foldr Abs (ObjectLiteral memberNames) (map (\n -> Left . Ident $ '_' : show n) [1..max 1 (length deps)]))+      (foldr (Abs . (\n -> Left . Ident $ '_' : show n)) (ObjectLiteral memberNames) [1..max 1 (length deps)])       (quantify (if null deps then-                   function unit (TypeApp (TypeConstructor name) ty)+                   function unit (foldl TypeApp (TypeConstructor name) tys)                  else-                   foldr function (TypeApp (TypeConstructor name) ty) (map (\(pn, ty') -> TypeApp (TypeConstructor pn) ty') deps)))+                   foldr (function . (\(pn, tys') -> foldl TypeApp (TypeConstructor pn) tys')) (foldl TypeApp (TypeConstructor name) tys) deps))     )   where   memberToNameAndValue :: [(String, Type)] -> Declaration -> Desugar (String, Value)-  memberToNameAndValue tys (ValueDeclaration ident _ _ _) = do-    memberType <- lift . maybe (Left "Type class member type not found") Right $ lookup (identToJs ident) tys-    memberName <- mkDictionaryEntryName mn name ty ident+  memberToNameAndValue tys' (ValueDeclaration ident _ _ _) = do+    memberType <- lift . maybe (Left "Type class member type not found") Right $ lookup (identToJs ident) tys'+    memberName <- mkDictionaryEntryName mn name tys ident     return (identToJs ident, TypedValue False                                (foldl App (Var (Qualified Nothing memberName)) (map (\n -> Var (Qualified Nothing (Ident ('_' : show n)))) [1..length deps]))                                (quantify memberType))   memberToNameAndValue _ _ = error "Invalid declaration in type instance definition" -typeInstanceDictionaryEntryDeclaration :: ModuleName -> [(Qualified ProperName, Type)] -> Qualified ProperName -> Type -> Declaration -> Desugar Declaration-typeInstanceDictionaryEntryDeclaration mn deps name ty (ValueDeclaration ident [] _ val) = do+typeInstanceDictionaryEntryDeclaration :: ModuleName -> [(Qualified ProperName, [Type])] -> Qualified ProperName -> [Type] -> Declaration -> Desugar Declaration+typeInstanceDictionaryEntryDeclaration mn deps name tys (ValueDeclaration ident [] _ val) = do   m <- get-  valTy <- lift $ do (arg, members) <- lookupTypeClass m+  valTy <- lift $ do (args, members) <- lookupTypeClass m                      ty' <- lookupIdent members-                     return $ replaceTypeVars arg ty ty'-  entryName <- mkDictionaryEntryName mn name ty ident+                     return $ replaceAllTypeVars (zip args tys) ty'+  entryName <- mkDictionaryEntryName mn name tys ident   return $ ValueDeclaration entryName [] Nothing     (TypedValue True val (quantify (if null deps then valTy else ConstrainedType deps valTy)))   where@@ -164,10 +162,10 @@ -- | -- Generate a name for a type class dictionary, based on the module name, class name and type name ---mkDictionaryValueName :: ModuleName -> Qualified ProperName -> Type -> Either String Ident-mkDictionaryValueName mn cl ty = do-  tyStr <- typeToString mn ty-  return $ Ident $ "__" ++ qualifiedToString mn cl ++ "_" ++ tyStr+mkDictionaryValueName :: ModuleName -> Qualified ProperName -> [Type] -> Either String Ident+mkDictionaryValueName mn cl tys = do+  tyStr <- mapM (typeToString mn) tys+  return $ Ident $ "__" ++ qualifiedToString mn cl ++ "_" ++ intercalate "_" tyStr  typeToString :: ModuleName -> Type -> Either String String typeToString _ (TypeVar _) = return "var"@@ -179,7 +177,7 @@ -- Generate a name for a type class dictionary member, based on the module name, class name, type name and -- member name ---mkDictionaryEntryName :: ModuleName -> Qualified ProperName -> Type -> Ident -> Desugar Ident-mkDictionaryEntryName mn name ty ident = do-  Ident dictName <- lift $ mkDictionaryValueName mn name ty+mkDictionaryEntryName :: ModuleName -> Qualified ProperName -> [Type] -> Ident -> Desugar Ident+mkDictionaryEntryName mn name tys ident = do+  Ident dictName <- lift $ mkDictionaryValueName mn name tys   return $ Escaped $ dictName ++ "_" ++ identToJs ident
src/Language/PureScript/TypeChecker.hs view
@@ -86,7 +86,7 @@   putEnv (env { names = M.insert (moduleName, name) (qualifyAllUnqualifiedNames moduleName env ty, Value) (names env) })  addTypeClassDictionaries :: [TypeClassDictionaryInScope] -> Check ()-addTypeClassDictionaries entries = do+addTypeClassDictionaries entries =   modify $ \st -> st { checkEnv = (checkEnv st) { typeClassDictionaries = entries ++ (typeClassDictionaries . checkEnv $ st) } }  checkTypeClassInstance :: ModuleName -> Type -> Check ()@@ -154,7 +154,7 @@     return $ ValueDeclaration name [] Nothing val'   ds <- typeCheckAll mainModuleName moduleName rest   return $ d : ds-typeCheckAll _ _ (ValueDeclaration _ _ _ _ : _) = error "Binders were not desugared"+typeCheckAll _ _ (ValueDeclaration{} : _) = error "Binders were not desugared" typeCheckAll mainModuleName moduleName (BindingGroupDeclaration vals : rest) = do   d <- rethrow (("Error in binding group " ++ show (map fst vals) ++ ":\n") ++) $ do     forM_ (map fst vals) $ \name ->@@ -206,7 +206,7 @@   filterModule = filter ((== moduleName) . fst) . M.keys   moduleExists env = not (null (filterModule (names env))) || not (null (filterModule (types env)))   shadowIdents idents' env =-    forM_ idents' $ \ident -> do+    forM_ idents' $ \ident ->       case (moduleName, ident) `M.lookup` names env of         Just (_, Alias _ _) -> return ()         Just (pt, _) -> do@@ -214,7 +214,7 @@           modifyEnv (\e -> e { names = M.insert (currentModule, ident) (pt, Alias moduleName ident) (names e) })         Nothing -> throwError (show moduleName ++ "." ++ show ident ++ " is undefined")   shadowTypes pns env =-    forM_ pns $ \pn -> do+    forM_ pns $ \pn ->       case (moduleName, pn) `M.lookup` types env of         Nothing -> throwError (show moduleName ++ "." ++ show pn ++ " is undefined")         Just (_, DataAlias _ _) -> return ()@@ -222,7 +222,7 @@           guardWith (show currentModule ++ "." ++ show pn ++ " is already defined") $ (currentModule, pn) `M.notMember` types env           modifyEnv (\e -> e { types = M.insert (currentModule, pn) (k, DataAlias moduleName pn) (types e) })           let keys = map (snd . fst) . filter (\(_, (fn, _)) -> fn `constructs` pn) . M.toList . dataConstructors $ env-          forM_ keys $ \dctor -> do+          forM_ keys $ \dctor ->             case (moduleName, dctor) `M.lookup` dataConstructors env of               Just (_, Alias _ _) -> return ()               Just (ctorTy, _) -> do@@ -236,23 +236,23 @@                     ) (typeClassDictionaries env)     forM_ instances $ \tcd -> do       let (Qualified _ ident) = tcdName tcd-      addTypeClassDictionaries [tcd { tcdName = (Qualified (Just currentModule) ident), tcdType = TCDAlias (tcdName tcd) }]+      addTypeClassDictionaries [tcd { tcdName = Qualified (Just currentModule) ident, tcdType = TCDAlias (tcdName tcd) }]   constructs (TypeConstructor (Qualified (Just mn) pn')) pn     = mn == moduleName && pn' == pn   constructs (ForAll _ ty _) pn = ty `constructs` pn   constructs (TypeApp (TypeApp t _) ty) pn | t == tyFunction = ty `constructs` pn   constructs (TypeApp ty _) pn = ty `constructs` pn   constructs fn _ = error $ "Invalid arguments to constructs: " ++ show fn-typeCheckAll mainModuleName moduleName (d@(TypeClassDeclaration _ _ _) : rest) = do+typeCheckAll mainModuleName moduleName (d@TypeClassDeclaration{} : rest) = do   env <- getEnv   ds <- typeCheckAll mainModuleName moduleName rest   return $ qualifyAllUnqualifiedNames moduleName env d : ds-typeCheckAll mainModuleName moduleName (d@(TypeInstanceDeclaration deps className ty _) : rest) = do+typeCheckAll mainModuleName moduleName (d@(TypeInstanceDeclaration deps className tys _) : rest) = do   env <- getEnv-  dictName <- Check . lift $ mkDictionaryValueName moduleName className ty-  checkTypeClassInstance moduleName ty-  forM_ deps $ checkTypeClassInstance moduleName . snd+  dictName <- Check . lift $ mkDictionaryValueName moduleName className tys+  mapM_ (checkTypeClassInstance moduleName) tys+  forM_ deps $ mapM_ (checkTypeClassInstance moduleName) . snd   addTypeClassDictionaries (qualifyAllUnqualifiedNames moduleName env-    [TypeClassDictionaryInScope (Qualified (Just moduleName) dictName) className ty (Just deps) TCDRegular])+    [TypeClassDictionaryInScope (Qualified (Just moduleName) dictName) className tys (Just deps) TCDRegular])   ds <- typeCheckAll mainModuleName moduleName rest   return $ qualifyAllUnqualifiedNames moduleName env d : ds
src/Language/PureScript/TypeChecker/Kinds.hs view
@@ -14,7 +14,6 @@ -----------------------------------------------------------------------------  {-# OPTIONS_GHC -fno-warn-orphans #-}-{-# LANGUAGE DeriveDataTypeable #-} {-# LANGUAGE MultiParamTypeClasses #-}  module Language.PureScript.TypeChecker.Kinds (@@ -31,7 +30,6 @@  import Control.Monad.State import Control.Monad.Error-import Control.Monad.Reader import Control.Monad.Unify  import Control.Applicative@@ -59,7 +57,7 @@ -- Infer the kind of a single type -- kindOf :: ModuleName -> Type -> Check Kind-kindOf moduleName ty =+kindOf _ ty =   rethrow (("Error checking kind of " ++ prettyPrintType ty ++ ":\n") ++) $     fmap tidyUp . liftUnify $ starIfUnknown <$> infer ty   where@@ -87,8 +85,8 @@   let dict = zipWith (\(name, _, _) var -> (name, var)) syns synVars   bindLocalTypeVariables moduleName dict $ do     tyCons <- replicateM (length tys) fresh-    let dict = zipWith (\(name, _, _) tyCon -> (name, tyCon)) tys tyCons-    bindLocalTypeVariables moduleName dict $ do+    let dict' = zipWith (\(name, _, _) tyCon -> (name, tyCon)) tys tyCons+    bindLocalTypeVariables moduleName dict' $ do       data_ks <- zipWithM (\tyCon (_, args, ts) -> do         kargs <- replicateM (length args) fresh         let argDict = zip (map ProperName args) kargs@@ -159,7 +157,9 @@   k2 =?= Row k1   return $ Row k1 infer (ConstrainedType deps ty) = do-  mapM_ (infer . snd) deps+  forM_ deps $ \(className, tys) -> do+    _ <- infer $ foldl TypeApp (TypeConstructor className) tys+    return ()   k <- infer ty   k =?= Star   return Star
src/Language/PureScript/TypeChecker/Monad.hs view
@@ -13,8 +13,8 @@ -- ----------------------------------------------------------------------------- -{-# LANGUAGE GeneralizedNewtypeDeriving, FlexibleInstances, RankNTypes, DeriveDataTypeable,-    GADTs, StandaloneDeriving, MultiParamTypeClasses, FlexibleContexts #-}+{-# LANGUAGE GeneralizedNewtypeDeriving, FlexibleInstances, RankNTypes,+    MultiParamTypeClasses, FlexibleContexts #-}  module Language.PureScript.TypeChecker.Monad where @@ -26,15 +26,13 @@  import Data.Data import Data.Maybe-import Data.Monoid import Data.Generics (mkT, everywhere)  import Control.Applicative import Control.Monad.State import Control.Monad.Error-import Control.Monad.Reader import Control.Monad.Unify-import Control.Arrow ((***))+import Control.Arrow (first)  import qualified Data.Map as M @@ -173,15 +171,15 @@ -- Temporarily bind a collection of names to local variables -- bindLocalVariables :: (Functor m, MonadState CheckState m) => ModuleName -> [(Ident, Type)] -> m a -> m a-bindLocalVariables moduleName bindings action =-  bindNames (M.fromList $ flip map bindings $ \(name, ty) -> ((moduleName, name), (ty, LocalVariable))) action+bindLocalVariables moduleName bindings =+  bindNames (M.fromList $ flip map bindings $ \(name, ty) -> ((moduleName, name), (ty, LocalVariable)))  -- | -- Temporarily bind a collection of names to local type variables -- bindLocalTypeVariables :: (Functor m, MonadState CheckState m) => ModuleName -> [(ProperName, Kind)] -> m a -> m a-bindLocalTypeVariables moduleName bindings action =-  bindTypes (M.fromList $ flip map bindings $ \(name, k) -> ((moduleName, name), (k, LocalTypeVariable))) action+bindLocalTypeVariables moduleName bindings =+  bindTypes (M.fromList $ flip map bindings $ \(name, k) -> ((moduleName, name), (k, LocalTypeVariable)))  -- | -- Lookup the type of a value by name in the @Environment@@@ -322,7 +320,7 @@   case e of     Left err -> throwError err     Right (a, ust) -> do-      modify $ \st -> st { checkNextVar = unifyNextVar ust }+      modify $ \st' -> st' { checkNextVar = unifyNextVar ust }       return (a, unifyCurrentSubstitution ust)  -- |@@ -334,7 +332,7 @@   go :: Type -> Type   go (TypeConstructor nm) = TypeConstructor $ qualify' nm   go (SaturatedTypeSynonym nm args) = SaturatedTypeSynonym (qualify' nm) args-  go (ConstrainedType constraints ty) = ConstrainedType (map (qualify' *** id) constraints) ty+  go (ConstrainedType constraints ty) = ConstrainedType (map (first qualify') constraints) ty   go other = other   qualify' qual = let (mn', pn') = canonicalizeType mn env qual                   in Qualified (Just mn') pn'
src/Language/PureScript/TypeChecker/Types.hs view
@@ -14,7 +14,6 @@ -----------------------------------------------------------------------------  {-# OPTIONS_GHC -fno-warn-orphans #-}-{-# LANGUAGE DeriveDataTypeable #-} {-# LANGUAGE FlexibleContexts #-} {-# LANGUAGE MultiParamTypeClasses #-} @@ -60,7 +59,6 @@  import Control.Monad.State import Control.Monad.Error-import Control.Monad.Reader import Control.Monad.Unify  import Control.Applicative@@ -82,7 +80,7 @@ -- Unify two types, updating the current substitution -- 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 = rethrow (\e -> "Error unifying type " ++ prettyPrintType t1 ++ " with type " ++ prettyPrintType t2 ++ ":\n" ++ e) $   unifyTypes' t1 t2   where   unifyTypes' (TUnknown u1) (TUnknown u2) | u1 == u2 = return ()@@ -104,8 +102,8 @@     sko <- newSkolemConstant     let sk = skolemize ident sko sc ty1     sk `unifyTypes` ty2-  unifyTypes' (ForAll _ _ _) _ = throwError "Skolem variable scope is unspecified"-  unifyTypes' ty f@(ForAll _ _ _) = f `unifyTypes` ty+  unifyTypes' ForAll{} _ = throwError "Skolem variable scope is unspecified"+  unifyTypes' ty f@ForAll{} = f `unifyTypes` ty   unifyTypes' (Object row1) (Object row2) = row1 =?= row2   unifyTypes' (TypeVar v1) (TypeVar v2) | v1 == v2 = return ()   unifyTypes' (TypeConstructor c1) (TypeConstructor c2) = do@@ -116,8 +114,8 @@     t3 `unifyTypes` t5     t4 `unifyTypes` t6   unifyTypes' (Skolem s1 _) (Skolem s2 _) | s1 == s2 = return ()-  unifyTypes' r1@(RCons _ _ _) r2 = unifyRows r1 r2-  unifyTypes' r1 r2@(RCons _ _ _) = unifyRows r1 r2+  unifyTypes' r1@RCons{} r2 = unifyRows r1 r2+  unifyTypes' r1 r2@RCons{} = unifyRows r1 r2   unifyTypes' r1@REmpty r2 = unifyRows r1 r2   unifyTypes' r1 r2@REmpty = unifyRows r1 r2   unifyTypes' t3 t4 = throwError $ "Cannot unify " ++ prettyPrintType t3 ++ " with " ++ prettyPrintType t4 ++ "."@@ -187,30 +185,30 @@       -- If the declaration is a function, it has access to other values in the binding group.       -- If not, the generated code might fail at runtime since those values might be undefined.       let dict' = if isFunction val then dict else M.empty-      triple@(_, (val, ty)) <- case e of+      triple@(_, (val', ty)) <- case e of         -- Typed declarations-        (ident, (val, Just (ty, checkType))) -> do+        (ident, (val', Just (ty, checkType))) -> do           -- Kind check           kind <- liftCheck $ kindOf moduleName ty           guardWith ("Expected type of kind *, was " ++ prettyPrintKind kind) $ kind == Star           -- Check the type with the new names in scope           ty' <- introduceSkolemScope <=< replaceAllTypeSynonyms $ ty-          val' <- bindNames dict' $ if checkType-                                   then TypedValue True <$> check val ty' <*> pure ty'-                                   else return (TypedValue False val ty')-          return (ident, (val', ty'))+          val'' <- bindNames dict' $ if checkType+                                   then TypedValue True <$> check val' ty' <*> pure ty'+                                   else return (TypedValue False val' ty')+          return (ident, (val'', ty'))         -- Untyped declarations-        (ident, (val, Nothing)) -> do+        (ident, (val', Nothing)) -> do           -- Infer the type with the new names in scope-          TypedValue _ val' ty <- bindNames dict' $ infer val+          TypedValue _ val'' ty <- bindNames dict' $ infer val'           ty =?= fromMaybe (error "name not found in dictionary") (lookup ident untypedDict)-          return (ident, (TypedValue True val' ty, ty))+          return (ident, (TypedValue True val'' ty, ty))       -- If --main is enabled, need to check that `main` has type Eff eff a for some eff, a       when (Just moduleName == mainModuleName && 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 "Control", ProperName "Monad", ProperName "Eff"])) (ProperName "Eff"))) eff) a       -- Make sure unification variables do not escape-      escapeCheck val ty+      escapeCheck val' ty       return triple   forM tys $ \(ident, (val, ty)) -> do     -- Replace type class dictionary placeholders with actual dictionaries@@ -221,7 +219,7 @@     -- top-level unification variables with named type variables.     let val'' = overTypes (desaturateAllTypeSynonyms . setifyAll) val'         ty' = varIfUnknown . desaturateAllTypeSynonyms . setifyAll $ ty-    return $ (ident, (val'', ty'))+    return (ident, (val'', ty'))   where   -- Apply the substitution that was returned from runUnify to both types and (type-annotated) values   tidyUp (ts, sub) = map (\(i, (val, ty)) -> (i, (overTypes (sub $?) val, sub $? ty))) ts@@ -260,14 +258,14 @@ -- Check that the current set of type class dictionaries entail the specified type class goal, and, if so, -- return a type class dictionary reference. ---entails :: ModuleName -> [TypeClassDictionaryInScope] -> (Qualified ProperName, Type) -> Check Value-entails moduleName context goal@(className, ty) = do+entails :: ModuleName -> [TypeClassDictionaryInScope] -> (Qualified ProperName, [Type]) -> Check Value+entails moduleName context goal@(className, tys) = do   env <- getEnv   case go env goal of-    [] -> throwError $ "No " ++ show className ++ " instance found for " ++ prettyPrintType ty+    [] -> throwError $ "No " ++ show className ++ " instance found for " ++ intercalate ", " (map prettyPrintType tys)     (dict : _) -> return dict   where-  go env (className', ty') =+  go env (className', tys') =     [ mkDictionary (canonicalizeDictionary tcd) args     | tcd <- context     -- Choose type class dictionaries in scope in the current module@@ -275,16 +273,16 @@     -- Make sure the type class name matches the one we are trying to satisfy     , typeConstructorsAreEqual env moduleName className' (tcdClassName tcd)     -- Make sure the type unifies with the type in the type instance definition-    , subst <- maybeToList $ typeHeadsAreEqual moduleName env ty' (tcdInstanceType tcd)+    , subst <- maybeToList . (>>= verifySubstitution) . fmap concat $ zipWithM (typeHeadsAreEqual moduleName env) tys' (tcdInstanceTypes tcd)     -- Solve any necessary subgoals     , args <- solveSubgoals env subst (tcdDependencies tcd) ]   -- Create dictionaries for subgoals which still need to be solved by calling go recursively   -- E.g. the goal (Show a, Show b) => Show (Either a b) can be satisfied if the current type   -- unifies with Either a b, and we can satisfy the subgoals Show a and Show b recursively.-  solveSubgoals :: Environment -> [(String, Type)] -> Maybe [(Qualified ProperName, Type)] -> [Maybe [Value]]+  solveSubgoals :: Environment -> [(String, Type)] -> Maybe [(Qualified ProperName, [Type])] -> [Maybe [Value]]   solveSubgoals _ _ Nothing = return Nothing   solveSubgoals env subst (Just subgoals) = do-    dict <- mapM (go env) (map (id *** replaceAllTypeVars subst) subgoals)+    dict <- mapM (go env . second (map (replaceAllTypeVars subst))) subgoals     return $ Just dict   -- Make a dictionary from subgoal dictionaries by applying the correct function   mkDictionary :: Qualified Ident -> Maybe [Value] -> Value@@ -301,6 +299,12 @@   canonicalizeDictionary :: TypeClassDictionaryInScope -> Qualified Ident   canonicalizeDictionary (TypeClassDictionaryInScope { tcdType = TCDRegular, tcdName = nm }) = nm   canonicalizeDictionary (TypeClassDictionaryInScope { tcdType = TCDAlias nm }) = nm+  -- Ensure that a substitution is valid+  verifySubstitution :: [(String, Type)] -> Maybe [(String, Type)]+  verifySubstitution subst = do+    let grps = groupBy ((==) `on` fst) subst+    guard (all ((==) 1 . length . nubBy ((==) `on` snd)) grps)+    return $ map head grps  -- | -- Check whether the type heads of two types are equal (for the purposes of type class dictionary lookup),@@ -314,7 +318,7 @@ typeHeadsAreEqual m e (TypeApp h1 (TypeVar v)) (TypeApp h2 arg) = (:) (v, arg) <$> typeHeadsAreEqual m e h1 h2 typeHeadsAreEqual m e t1@(TypeApp _ _) t2@(TypeApp _ (TypeVar _)) = typeHeadsAreEqual m e t2 t1 typeHeadsAreEqual m e (SaturatedTypeSynonym name args) t2 = case expandTypeSynonym' e m name args of-  Left err -> Nothing+  Left  _  -> Nothing   Right t1 -> typeHeadsAreEqual m e t1 t2 typeHeadsAreEqual _ _ _ _ = Nothing @@ -344,7 +348,7 @@ -- skolemEscapeCheck :: Value -> Check () skolemEscapeCheck (TypedValue False _ _) = return ()-skolemEscapeCheck root@(TypedValue _ _ _) =+skolemEscapeCheck root@TypedValue{} =   -- Every skolem variable is created when a ForAll type is skolemized.   -- This determines the scope of that skolem variable, which is copied from the SkolemScope   -- field of the ForAll constructor.@@ -368,10 +372,10 @@       collect _ = []   go _ scos = ([], scos)   findBindingScope :: SkolemScope -> Maybe Value-  findBindingScope sco = something (mkQ Nothing go) root+  findBindingScope sco = something (mkQ Nothing go') root     where-    go val@(TypedValue _ _ (ForAll _ _ (Just sco'))) | sco == sco' = Just val-    go _ = Nothing+    go' val@(TypedValue _ _ (ForAll _ _ (Just sco'))) | sco == sco' = Just val+    go' _ = Nothing skolemEscapeCheck val = throwError $ "Untyped value passed to skolemEscapeCheck: " ++ prettyPrintValue val  -- |@@ -393,19 +397,13 @@ varIfUnknown ty =   let unks = nub $ unknowns ty       toName = (:) 't' . show-      ty' = everywhere (mkT typeToVar) $ ty+      ty' = everywhere (mkT typeToVar) ty       typeToVar :: Type -> Type       typeToVar (TUnknown (Unknown u)) = TypeVar (toName u)       typeToVar t = t   in mkForAll (sort . map (toName . runUnknown) $ unks) ty'  -- |--- Replace named type variables with types----replaceAllTypeVars :: [(String, Type)] -> Type -> Type-replaceAllTypeVars = foldl' (\f (name, ty) -> replaceTypeVars name ty . f) id---- | -- Remove any ForAlls and ConstrainedType constructors in a type by introducing new unknowns -- or TypeClassDictionary values. --@@ -430,7 +428,7 @@ replaceVarWithUnknown :: String -> Type -> UnifyT Type Check Type replaceVarWithUnknown ident ty = do   tu <- fresh-  return $ replaceTypeVars ident tu $ ty+  return $ replaceTypeVars ident tu ty  -- | -- Replace fully applied type synonyms with the @SaturatedTypeSynonym@ data constructor, which helps generate@@ -603,11 +601,11 @@       (_, fn) <- instantiatePolyTypeWithUnknowns (error "Data constructor types cannot contains constraints") ty       go binders fn         where-        go [] ty = do-          subsumes Nothing val ty+        go [] ty' = do+          subsumes Nothing val ty'           return M.empty-        go (binder : binders) (TypeApp (TypeApp t obj) ret) | t == tyFunction =-          M.union <$> inferBinder obj binder <*> go binders ret+        go (binder : binders') (TypeApp (TypeApp t obj) ret) | t == tyFunction =+          M.union <$> inferBinder obj binder <*> go binders' ret         go _ _ = throwError $ "Wrong number of arguments to constructor " ++ show ctor     _ -> throwError $ "Constructor " ++ show ctor ++ " is not defined" inferBinder val (ObjectBinder props) = do@@ -713,7 +711,7 @@ -- Check the type of a value -- check' :: Value -> Type -> UnifyT Type Check Value-check' val t@(ForAll ident ty _) = do+check' val (ForAll ident ty _) = do   scope <- newSkolemScope   sko <- newSkolemConstant   let sk = skolemize ident sko scope ty@@ -722,15 +720,15 @@ check' val t@(ConstrainedType constraints ty) = do   env <- getEnv   Just moduleName <- checkCurrentModule <$> get-  dictNames <- flip mapM constraints $ \(Qualified _ (ProperName className), _) -> do+  dictNames <- forM constraints $ \(Qualified _ (ProperName className), _) -> do     n <- liftCheck freshDictionaryName     return $ Ident $ "__dict_" ++ className ++ "_" ++ show n   val' <- withTypeClassDictionaries (zipWith (\name (className, instanceTy) ->     TypeClassDictionaryInScope name className instanceTy Nothing TCDRegular) (map (Qualified Nothing) dictNames)       (qualifyAllUnqualifiedNames moduleName env constraints)) $         check val ty-  return $ TypedValue True (foldr Abs val' (map Left dictNames)) t-check' val t@(SaturatedTypeSynonym name args) = do+  return $ TypedValue True (foldr (Abs . Left) val' dictNames) t+check' val (SaturatedTypeSynonym name args) = do   ty <- introduceSkolemScope <=< expandTypeSynonym name $ args   val' <- check val ty   return $ TypedValue True val' ty@@ -747,8 +745,8 @@ check' v@(BooleanLiteral _) t | t == tyBoolean =   return $ TypedValue True v t check' (ArrayLiteral vals) t@(TypeApp a ty) | a == tyArray = do-  arr <- ArrayLiteral <$> forM vals (\val -> check val ty)-  return $ TypedValue True arr t+  array <- ArrayLiteral <$> forM vals (`check` ty)+  return $ TypedValue True array t check' (Abs (Left arg) ret) ty@(TypeApp (TypeApp t argTy) retTy) | t == tyFunction = do   Just moduleName <- checkCurrentModule <$> get   ret' <- bindLocalVariables moduleName [(arg, argTy)] $ check ret retTy@@ -944,17 +942,17 @@   go ts1' ts2' r1' r2'   return val   where-  go [] ts2 r1 r2 = r1 =?= rowFromList (ts2, r2)-  go ts1 [] r1 r2 = r2 =?= rowFromList (ts1, r1)-  go ((p1, ty1) : ts1) ((p2, ty2) : ts2) r1 r2+  go [] ts2 r1' r2' = r1' =?= rowFromList (ts2, r2')+  go ts1 [] r1' r2' = r2' =?= rowFromList (ts1, r1')+  go ((p1, ty1) : ts1) ((p2, ty2) : ts2) r1' r2'     | p1 == p2 = do subsumes Nothing ty1 ty2-                    go ts1 ts2 r1 r2+                    go ts1 ts2 r1' r2'     | p1 < p2 = do rest <- fresh-                   r2 =?= RCons p1 ty1 rest-                   go ts1 ((p2, ty2) : ts2) r1 rest+                   r2' =?= RCons p1 ty1 rest+                   go ts1 ((p2, ty2) : ts2) r1' rest     | p1 > p2 = do rest <- fresh-                   r1 =?= RCons p2 ty2 rest-                   go ((p1, ty1) : ts1) ts2 rest r2+                   r1' =?= RCons p2 ty2 rest+                   go ((p1, ty1) : ts1) ts2 rest r2' subsumes' val ty1 ty2@(Object _) = subsumes val ty2 ty1 subsumes' val ty1 ty2 = do   ty1 =?= ty2
src/Language/PureScript/Types.hs view
@@ -19,10 +19,10 @@  import Data.Data import Data.List (nub)-import Data.Generics (everything, mkT, mkQ, everywhereBut)+import Data.Generics (everything, mkQ)  import Control.Monad.Unify-import Control.Arrow ((***))+import Control.Arrow (second)  import Language.PureScript.Names @@ -66,7 +66,7 @@   -- |   -- A type with a set of type class constraints   ---  | ConstrainedType [(Qualified ProperName, Type)] Type+  | ConstrainedType [(Qualified ProperName, [Type])] Type   -- |   -- A skolem constant   --@@ -122,7 +122,7 @@ -- Smart constructor for function types -- function :: Type -> Type -> Type-function t1 t2 = TypeApp (TypeApp tyFunction t1) t2+function t1 = TypeApp (TypeApp tyFunction t1)  -- | -- Convert a row to a list of pairs of labels and types@@ -143,8 +143,8 @@ -- Check whether a type is a monotype -- isMonoType :: Type -> Bool-isMonoType (ForAll _ _ _) = False-isMonoType ty = True+isMonoType ForAll{} = False+isMonoType _        = True  -- | -- Universally quantify a type@@ -168,17 +168,17 @@     where     go :: [String] -> Type -> Type     go bs (Object r) = Object $ go bs r-    go bs (TypeVar v) | v == name = replacement+    go _  (TypeVar v) | v == name = replacement     go bs (TypeApp t1 t2) = TypeApp (go bs t1) (go bs t2)-    go bs (SaturatedTypeSynonym name ts) = SaturatedTypeSynonym name $ map (go bs) ts+    go bs (SaturatedTypeSynonym name' ts) = SaturatedTypeSynonym name' $ map (go bs) ts     go bs f@(ForAll v t sco) | v == name = f                              | v `elem` usedTypeVariables replacement =                                  let v' = genName v (name : bs ++ usedTypeVariables replacement)                                      t' = replaceTypeVars' bs v (TypeVar v') t                                  in ForAll v' (go (v' : bs) t') sco                              | otherwise = ForAll v (go (v : bs) t) sco-    go bs (ConstrainedType cs t) = ConstrainedType (map (id *** go bs) cs) (go bs t)-    go bs (RCons name t r) = RCons name (go bs t) (go bs r)+    go bs (ConstrainedType cs t) = ConstrainedType (map (second $ map (go bs)) cs) (go bs t)+    go bs (RCons name' t r) = RCons name' (go bs t) (go bs r)     go _ ty = ty   genName orig inUse = try 0     where@@ -186,6 +186,12 @@           | otherwise = orig ++ show n  -- |+-- Replace named type variables with types+--+replaceAllTypeVars :: [(String, Type)] -> Type -> Type+replaceAllTypeVars = foldl (\f (name, ty) -> replaceTypeVars name ty . f) id++-- | -- Collect all type variables appearing in a type -- usedTypeVariables :: Type -> [String]@@ -206,7 +212,7 @@   go bound (TypeApp t1 t2) = go bound t1 ++ go bound t2   go bound (SaturatedTypeSynonym _ ts) = concatMap (go bound) ts   go bound (ForAll v t _) = go (v : bound) t-  go bound (ConstrainedType cs t) = concatMap (go bound . snd) cs ++ go bound t+  go bound (ConstrainedType cs t) = concatMap (concatMap (go bound) . snd) cs ++ go bound t   go bound (RCons _ t r) = go bound t ++ go bound r   go _ _ = [] 
src/Language/PureScript/Values.hs view
@@ -112,7 +112,7 @@   -- can be evaluated at runtime. The constructor arguments represent (in order): the type class name and   -- instance type, and the type class dictionaries in scope.   ---  | TypeClassDictionary (Qualified ProperName, Type) [TypeClassDictionaryInScope] deriving (Show, Data, Typeable)+  | TypeClassDictionary (Qualified ProperName, [Type]) [TypeClassDictionaryInScope] deriving (Show, Data, Typeable)  -- | -- The type of a type class dictionary@@ -141,13 +141,13 @@     --     , tcdClassName :: Qualified ProperName     -- |-    -- The type to which this type class instance applies+    -- The types to which this type class instance applies     ---    , tcdInstanceType :: Type+    , tcdInstanceTypes :: [Type]     -- |     -- Type class dependencies which must be satisfied to construct this dictionary     ---    , tcdDependencies :: Maybe [(Qualified ProperName, Type)]+    , tcdDependencies :: Maybe [(Qualified ProperName, [Type])]     -- |     -- The type of this dictionary     --
tests/Main.hs view
@@ -20,7 +20,6 @@  import Data.List (isSuffixOf) import Data.Traversable (traverse)-import Control.Applicative import Control.Monad import Control.Monad.Trans.Maybe (MaybeT(..), runMaybeT) import System.Exit@@ -31,7 +30,6 @@ import Text.Parsec (ParseError) import qualified Paths_purescript as Paths import qualified System.IO.UTF8 as U-import qualified Data.Map as M  preludeFilename :: IO FilePath preludeFilename = Paths.getDataFileName "prelude/prelude.purs"@@ -45,13 +43,13 @@ compile opts inputFiles = do   modules <- readInput inputFiles   case modules of-    Left parseError -> do+    Left parseError ->       return (Left $ show parseError)-    Right ms -> do+    Right ms ->       case P.compile opts ms of-        Left typeError -> do+        Left typeError ->           return (Left typeError)-        Right (js, _, _) -> do+        Right (js, _, _) ->           return (Right js)  assert :: P.Options -> [FilePath] -> (Either String String -> IO (Maybe String)) -> IO ()@@ -93,7 +91,7 @@ main :: IO () main = do   cd <- getCurrentDirectory-  putStrLn $ cd+  putStrLn cd   let examples = cd ++ pathSeparator : "examples"   let passing = examples ++ pathSeparator : "passing"   passingTestCases <- getDirectoryContents passing