git.iko.soy/rowtype-yoga/purescript-native
on golang help sign in
Remove multiple argument functions, allow type class instances for ->
commitb37c7300e854cc7e47fa220380a565c8dcd2c4d5 authorPhil Freeman <paf31@cantab.net> dateThu 30 Jan 2014, 17:55 (13 years ago) parent24679fb
26 files changed+141−173
examples/passing/Arrays.purs+2−2 examples/passing/ExternRaw.purs−2 examples/passing/Functions.purs+4−4 examples/passing/Import.purs+1−1 examples/passing/Operators.purs+4−4 examples/passing/TopLevelCase.purs+5−5 examples/passing/TypeClasses.purs+12−8 libraries/prelude/prelude.purs+4−4 psci/Main.hs+1−1 src/Language/PureScript/CodeGen/JS.hs+13−13 src/Language/PureScript/Declarations.hs+1−1 src/Language/PureScript/Parser/Declarations.hs+1−4 src/Language/PureScript/Parser/Types.hs+7−11 src/Language/PureScript/Parser/Values.hs+2−10 src/Language/PureScript/Pretty/Types.hs+2−8 src/Language/PureScript/Pretty/Values.hs+5−5 src/Language/PureScript/Scope.hs+1−1 src/Language/PureScript/Sugar/CaseDeclarations.hs+7−11 src/Language/PureScript/Sugar/DoNotation.hs+3−3 src/Language/PureScript/Sugar/Operators.hs+2−2 src/Language/PureScript/Sugar/TypeClasses.hs+5−6 src/Language/PureScript/TypeChecker.hs+2−2 src/Language/PureScript/TypeChecker/Kinds.hs+1−6 src/Language/PureScript/TypeChecker/Types.hs+46−44 src/Language/PureScript/Types.hs+8−13 src/Language/PureScript/Values.hs+2−2
examples/passing/Arrays.purs+2−2
@@ -10,9 +10,9 @@ test2 = \arr -> case arr of
1010
1111data Tree = One Number | Some [Tree]
1212
13−test3 = \(tree, sum) -> case tree of
13+test3 = \tree sum -> case tree of
1414 One n -> n
15− Some (n1 : n2 : rest) -> test3(n1, sum) * 10 + test3(n2, sum) * 5 + sum(rest)
15+ Some (n1 : n2 : rest) -> test3 n1 sum * 10 + test3 n2 sum * 5 + sum rest
1616
1717test4 = \arr -> case arr of
1818 [] -> 0
examples/passing/ExternRaw.purs−2
@@ -2,8 +2,6 @@ module ExternRaw where
22
33foreign import first "function first(xs) { return xs[0]; }" :: forall a. [a] -> a
44
5−foreign import cond "function cond(b, t, f) { return b ? t : f; }" :: forall a. (Boolean, a, a) -> a
6−
75foreign import loop "function loop() { while (true) {} }" :: forall a. a
86
97foreign import concat "function concat(xs) { \
examples/passing/Functions.purs+4−4
@@ -2,15 +2,15 @@ module Functions where
22
33 test1 = \ -> 0
44
5− test2 = \() -> 0
5+ test2 = \_ -> 0
66
7− test3 = \a (b, c) d -> a + b + c + d
7+ test3 = \a b c d -> a + b + c + d
88
9− test4 = \(a) -> a
9+ test4 = \a -> a
1010
1111 test5 = \(%%) -> 1 %% 2
1212
13− test6 = \((+++), (***)) -> 1 +++ 2 *** 3
13+ test6 = \(+++) (***) -> 1 +++ 2 *** 3
1414
1515module Main where
1616
examples/passing/Import.purs+1−1
@@ -9,7 +9,7 @@ module M2 where
99
1010 import M1
1111
12− main = \() -> foo 42
12+ main = \_ -> foo 42
1313
1414module Main where
1515
examples/passing/Operators.purs+4−4
@@ -12,11 +12,11 @@ module Operators1 where
1212
1313module Operators2 where
1414
15− test1 = \(x, y, z) -> x * y + z(x)(y)
15+ test1 = \x y z -> x * y + z(x)(y)
1616
1717 test2 = (\x -> x.foo false) { foo : \_ -> 1 }
1818
19− test3 = (\(x, y) -> x)(1 + 2 * (1 + 2), true && (false || false))
19+ test3 = (\x y -> x)(1 + 2 * (1 + 2)) (true && (false || false))
2020
2121 k = \x -> \y -> x
2222
@@ -30,7 +30,7 @@ module Operators2 where
3030
3131 test6 = ((\x -> x) `k` 2) 3
3232
33− (<>) = \s1 -> \s2 -> s1 ++ s2
33+ (<>) = \s1 s2 -> s1 ++ s2
3434
3535 test7 = "Hello" <> "World!"
3636
@@ -57,7 +57,7 @@ import Global
5757import Arrays
5858
5959main = do
60− print (test1 (1, 2, \x y -> x + y))
60+ print $ test1 1 2 $ \x y -> x + y
6161 print test2
6262 print test3
6363 print test4
examples/passing/TopLevelCase.purs+5−5
@@ -1,10 +1,10 @@
11module TopLevelCase where
22
3− gcd :: (Number, Number) -> Number
4− gcd (0, x) = x
5− gcd (x, 0) = x
6− gcd (x, y) | x > y = gcd (x % y, y)
7− gcd (x, y) = gcd (y % x, x)
3+ gcd :: Number -> Number -> Number
4+ gcd 0 x = x
5+ gcd x 0 = x
6+ gcd x y | x > y = gcd (x % y) y
7+ gcd x y = gcd (y % x) x
88
99 guardsTest (x:xs) | x > 0 = guardsTest xs
1010 guardsTest xs = xs
examples/passing/TypeClasses.purs+12−8
@@ -8,24 +8,24 @@ class Show a where
88instance Show String where
99 show s = s
1010
11−test1 = \ -> show "testing"
11+test1 = \_ -> show "testing"
1212
1313f :: forall a. (TypeClasses.Show a) => a -> String
1414f x = show x
1515
16−test2 = \ -> f "testing"
16+test2 = \_ -> f "testing"
1717
1818test7 :: forall a. (Show a) => a -> String
1919test7 = show
2020
21−test8 = \ -> show $ "testing"
21+test8 = \_ -> show $ "testing"
2222
2323data Data a = Data a
2424
2525instance (TypeClasses.Show a) => TypeClasses.Show (Data a) where
2626 show (Data a) = "Data (" ++ show a ++ ")"
2727
28−test3 = \ -> show (Data "testing")
28+test3 = \_ -> show (Data "testing")
2929
3030class Monad m where
3131 ret :: forall a. a -> m a
@@ -42,10 +42,10 @@ instance TypeClasses.Monad Maybe where
4242 (>>=) Nothing _ = Nothing
4343 (>>=) (Just a) f = f a
4444
45−test4 :: forall m. (Monad m) => () -> m Number
46−test4 = \ -> ret 1
45+test4 :: forall a m. (Monad m) => a -> m Number
46+test4 = \_ -> ret 1
4747
48−test5 = \ -> Just 1 >>= \n -> ret (n + 1)
48+test5 = \_ -> Just 1 >>= \n -> ret (n + 1)
4949
5050module TypeClasses2 where
5151
@@ -55,7 +55,11 @@ instance (TypeClasses.Show a) => TypeClasses.Show [a] where
5555 show [] = "[]"
5656 show (x:xs) = TypeClasses.show x ++ ", " ++ TypeClasses.show xs
5757
58−test6 = \ -> show ["testing"]
58+test6 = \_ -> show ["testing"]
59+
60+instance TypeClasses.Monad (->) r where
61+ ret a r = a
62+ (>>=) f g r = g (f r) r
5963
6064module Main where
6165
libraries/prelude/prelude.purs+4−4
@@ -406,15 +406,15 @@ module Math where
406406 , acos :: Number -> Number
407407 , asin :: Number -> Number
408408 , atan :: Number -> Number
409− , atan2 :: (Number, Number) -> Number
409+ --, atan2 :: (Number, Number) -> Number
410410 , aceil :: Number -> Number
411411 , cos :: Number -> Number
412412 , exp :: Number -> Number
413413 , floor :: Number -> Number
414414 , log :: Number -> Number
415− , max :: (Number, Number) -> Number
416− , pow :: (Number, Number) -> Number
417− , random :: () -> Number
415+ --, max :: (Number, Number) -> Number
416+ --, pow :: (Number, Number) -> Number
417+ --, random :: () -> Number
418418 , round :: Number -> Number
419419 , sin :: Number -> Number
420420 , sqrt :: Number -> Number
psci/Main.hs+1−1
@@ -64,7 +64,7 @@ createTemporaryModule imports value =
6464 trace = P.Var (P.Qualified (Just traceModule) (P.Ident "print"))
6565 mainDecl = P.ValueDeclaration (P.Ident "main") [] Nothing
6666 (P.Do [ P.DoNotationBind (P.VarBinder (P.Ident "it")) value
67− , P.DoNotationValue (P.App trace [ P.Var (P.Qualified Nothing (P.Ident "it")) ] )
67+ , P.DoNotationValue (P.App trace (P.Var (P.Qualified Nothing (P.Ident "it"))) )
6868 ])
6969 in
7070 P.Module moduleName $ map (importDecl . P.ModuleName) imports ++ [mainDecl]
src/Language/PureScript/CodeGen/JS.hs+13−13
@@ -110,9 +110,9 @@ valueToJs opts m e (Case values binders) = bindersToJs opts m e binders (map (va
110110valueToJs opts m e (IfThenElse cond th el) = JSConditional (valueToJs opts m e cond) (valueToJs opts m e th) (valueToJs opts m e el)
111111valueToJs opts m e (Accessor prop val) = JSAccessor prop (valueToJs opts m e val)
112112valueToJs opts m e (Indexer index val) = JSIndexer (valueToJs opts m e index) (valueToJs opts m e val)
113−valueToJs opts m e (App val args) = JSApp (valueToJs opts m e val) (map (valueToJs opts m e) args)
114−valueToJs opts m e (Abs args val) = JSFunction Nothing args (JSBlock [JSReturn (valueToJs opts m e val)])
115−valueToJs opts m e (TypedValue _ (Abs args val) ty) | optionsPerformRuntimeTypeChecks opts = JSFunction Nothing args (JSBlock $ runtimeTypeChecks args ty ++ [JSReturn (valueToJs opts m e val)])
113+valueToJs opts m e (App val arg) = JSApp (valueToJs opts m e val) [valueToJs opts m e arg]
114+valueToJs opts m e (Abs arg val) = JSFunction Nothing [arg] (JSBlock [JSReturn (valueToJs opts m e val)])
115+valueToJs opts m e (TypedValue _ (Abs arg val) ty) | optionsPerformRuntimeTypeChecks opts = JSFunction Nothing [arg] (JSBlock $ runtimeTypeChecks arg ty ++ [JSReturn (valueToJs opts m e val)])
116116valueToJs opts m e (Unary op val) = JSUnary op (valueToJs opts m e val)
117117valueToJs opts m e (Binary op v1 v2) = JSBinary op (valueToJs opts m e v1) (valueToJs opts m e v2)
118118valueToJs _ m e (Var ident) = varToJs m e ident
@@ -120,17 +120,17 @@ valueToJs opts m e (TypedValue _ val _) = valueToJs opts m e val
120120valueToJs _ _ _ (TypeClassDictionary _ _) = error "Type class dictionary was not replaced"
121121valueToJs _ _ _ _ = error "Invalid argument to valueToJs"
122122
123−runtimeTypeChecks :: [Ident] -> Type -> [JS]
124−runtimeTypeChecks args ty =
123+runtimeTypeChecks :: Ident -> Type -> [JS]
124+runtimeTypeChecks arg ty =
125125 let
126− argTys = getFunctionArgumentTypes ty
126+ argTy = getFunctionArgumentType ty
127127 in
128− concat $ zipWith argumentCheck (map JSVar args) argTys
128+ maybe [] (argumentCheck (JSVar arg)) argTy
129129 where
130− getFunctionArgumentTypes :: Type -> [Type]
131− getFunctionArgumentTypes (Function funArgs _) = funArgs
132− getFunctionArgumentTypes (ForAll _ ty') = getFunctionArgumentTypes ty'
133− getFunctionArgumentTypes _ = []
130+ getFunctionArgumentType :: Type -> Maybe Type
131+ getFunctionArgumentType (TypeApp (TypeApp Function funArg) _) = Just funArg
132+ getFunctionArgumentType (ForAll _ ty') = getFunctionArgumentType ty'
133+ getFunctionArgumentType _ = Nothing
134134 argumentCheck :: JS -> Type -> [JS]
135135 argumentCheck val Number = [typeCheck val "number"]
136136 argumentCheck val String = [typeCheck val "string"]
@@ -141,7 +141,7 @@ runtimeTypeChecks args ty =
141141 (pairs, _) = rowToList row
142142 in
143143 typeCheck val "object" : concatMap (\(prop, ty') -> argumentCheck (JSAccessor prop val) ty') pairs
144− argumentCheck val (Function _ _) = [typeCheck val "function"]
144+ argumentCheck val (TypeApp (TypeApp Function _) _) = [typeCheck val "function"]
145145 argumentCheck val (ForAll _ ty') = argumentCheck val ty'
146146 argumentCheck _ _ = []
147147 typeCheck :: JS -> String -> JS
@@ -253,7 +253,7 @@ isOnlyConstructor m e ctor =
253253 numConstructors ty = length $ filter (\(ty1, _) -> ((==) `on` typeConstructor) ty ty1) $ M.elems $ dataConstructors e
254254 typeConstructor (TypeConstructor qual) = qualify m qual
255255 typeConstructor (ForAll _ ty) = typeConstructor ty
256− typeConstructor (Function _ ty) = typeConstructor ty
256+ typeConstructor (TypeApp (TypeApp Function _) ty) = typeConstructor ty
257257 typeConstructor (TypeApp ty _) = typeConstructor ty
258258 typeConstructor fn = error $ "Invalid arguments to typeConstructor: " ++ show fn
259259
src/Language/PureScript/Declarations.hs+1−1
@@ -88,7 +88,7 @@ data Declaration
8888 -- |
8989 -- A value declaration (name, top-level binders, optional guard, value)
9090 --
91− | ValueDeclaration Ident [[Binder]] (Maybe Guard) Value
91+ | ValueDeclaration Ident [Binder] (Maybe Guard) Value
9292 -- |
9393 -- A minimal mutually recursive set of value declarations
9494 --
src/Language/PureScript/Parser/Declarations.hs+1−4
@@ -58,13 +58,10 @@ parseTypeSynonymDeclaration =
5858parseValueDeclaration :: P.Parsec String ParseState Declaration
5959parseValueDeclaration =
6060 ValueDeclaration <$> parseNonReservedIdent
61− <*> P.many parseTopLevelBinder
61+ <*> P.many parseBinderNoParens
6262 <*> P.optionMaybe parseGuard
6363 <*> ((lexeme (indented *> P.char '=')) *> parseValue)
6464
65−parseTopLevelBinder :: P.Parsec String ParseState [Binder]
66−parseTopLevelBinder = return <$> P.try parseBinderNoParens <|> parens (commaSep parseBinder)
67−
6865parseExternDeclaration :: P.Parsec String ParseState Declaration
6966parseExternDeclaration = P.try (reserved "foreign") *> indented *> (reserved "import") *> indented *>
7067 (ExternDataDeclaration <$> (P.try (reserved "data") *> indented *> properName)
src/Language/PureScript/Parser/Types.hs+7−11
@@ -41,16 +41,12 @@ parseArray = squares $ return Array
4141parseArrayOf :: P.Parsec String ParseState Type
4242parseArrayOf = squares $ TypeApp Array <$> parseType
4343
44+parseFunction :: P.Parsec String ParseState Type
45+parseFunction = parens $ P.try (lexeme (P.string "->")) >> return Function
46+
4447parseObject :: P.Parsec String ParseState Type
4548parseObject = braces $ Object <$> parseRow False
4649
47−parseFunction :: P.Parsec String ParseState Type
48−parseFunction = do
49− args <- lexeme $ parens $ commaSep parsePolyType
50− _ <- lexeme $ P.string "->"
51− resultType <- parseType
52− return $ Function args resultType
53−
5450parseTypeVariable :: P.Parsec String ParseState Type
5551parseTypeVariable = TypeVar <$> identifier
5652
@@ -68,12 +64,13 @@ parseTypeAtom = indented *> P.choice (map P.try
6864 , parseBoolean
6965 , parseArray
7066 , parseArrayOf
67+ , parseFunction
7168 , parseObject
7269 , parseTypeVariable
7370 , parseTypeConstructor
7471 , parseForAll
7572 , parens (parseRow True)
76− , parens parseType ])
73+ , parens parsePolyType ])
7774
7875parseConstrainedType :: P.Parsec String ParseState Type
7976parseConstrainedType = do
@@ -90,10 +87,10 @@ parseConstrainedType = do
9087 return $ maybe ty (flip ConstrainedType ty) constraints
9188
9289parseAnyType :: P.Parsec String ParseState Type
93−parseAnyType = (P.buildExpressionParser operators $ parseTypeAtom) <|> parseFunction P.<?> "type"
90+parseAnyType = (P.buildExpressionParser operators $ parseTypeAtom) P.<?> "type"
9491 where
9592 operators = [ [ P.Infix (return TypeApp) P.AssocLeft ]
96− , [ P.Infix (P.try (lexeme (P.string "->")) >> return (\t1 t2 -> Function [t1] t2)) P.AssocRight ] ]
93+ , [ P.Infix (P.try (lexeme (P.string "->")) >> return function) P.AssocRight ] ]
9794
9895-- |
9996-- Parse a monotype
@@ -110,7 +107,6 @@ parseType = do
110107parsePolyType :: P.Parsec String ParseState Type
111108parsePolyType = do
112109 ty <- parseAnyType
113− unless (isPolyType ty) $ P.unexpected "polymorphic type"
114110 return ty
115111
116112parseNameAndType :: P.Parsec String ParseState t -> P.Parsec String ParseState (String, t)
src/Language/PureScript/Parser/Values.hs+2−10
@@ -54,19 +54,12 @@ parseIdentifierAndValue = (,) <$> (C.indented *> C.identifier <* C.indented <* C
5454parseAbs :: P.Parsec String ParseState Value
5555parseAbs = do
5656 C.reservedOp "\\"
57− args <- P.many (C.indented *> (P.try singleArg <|> manyArgs))
57+ args <- P.many (C.indented *> (Abs <$> C.parseIdent))
5858 C.indented *> C.reservedOp "->"
5959 value <- parseValue
6060 return $ toFunction args value
6161 where
62− manyArgs :: P.Parsec String ParseState (Value -> Value)
63− manyArgs = do
64− args <- C.parens (C.commaSep C.parseIdent)
65− return $ Abs args
66− singleArg :: P.Parsec String ParseState (Value -> Value)
67− singleArg = Abs . return <$> C.parseIdent
6862 toFunction :: [Value -> Value] -> Value -> Value
69− toFunction [] value = Abs [] value
7063 toFunction args value = foldr (($)) value args
7164
7265parseVar :: P.Parsec String ParseState Value
@@ -159,8 +152,7 @@ parseValue =
159152 indexersAndAccessors = C.buildPostfixParser postfixTable1 parseValueAtom
160153 postfixTable1 = [ parseAccessor
161154 , \v -> P.try $ flip ObjectUpdate <$> (C.indented *> C.braces (C.commaSep1 (C.indented *> parsePropertyUpdate))) <*> pure v ]
162− postfixTable2 = [ \v -> P.try (C.indented *> indexersAndAccessors >>= \t2 -> return (\t1 -> App t1 [t2])) <*> pure v
163− , \v -> P.try $ flip App <$> (C.indented *> C.parens (C.commaSep parseValue)) <*> pure v
155+ postfixTable2 = [ \v -> P.try (C.indented *> indexersAndAccessors >>= return . flip App) <*> pure v
164156 , \v -> flip (TypedValue True) <$> (P.try (C.lexeme (C.indented *> P.string "::")) *> parsePolyType) <*> pure v
165157 ]
166158 operators = [ [ Prefix $ C.lexeme (P.try $ C.indented *> C.reservedOp "!") >> return (Unary Not)
src/Language/PureScript/Pretty/Types.hs+2−8
@@ -35,6 +35,7 @@ typeLiterals = mkPattern match
3535 match String = Just "String"
3636 match Boolean = Just "Boolean"
3737 match Array = Just $ "[]"
38+ match Function = Just $ "(->)"
3839 match (Object row) = Just $ "{ " ++ prettyPrintType row ++ " }"
3940 match (TypeVar var) = Just var
4041 match (TypeConstructor ctor) = Just $ show ctor
@@ -74,13 +75,7 @@ typeApp = mkPattern match
7475singleArgumentFunction :: Pattern () Type (Type, Type)
7576singleArgumentFunction = mkPattern match
7677 where
77− match (Function [arg] ret) = Just (arg, ret)
78− match _ = Nothing
79−
80−function :: Pattern () Type ([Type], Type)
81−function = mkPattern match
82− where
83− match (Function args ret) = Just (args, ret)
78+ match (TypeApp (TypeApp Function arg) ret) = Just (arg, ret)
8479 match _ = Nothing
8580
8681-- |
@@ -95,6 +90,5 @@ prettyPrintType = fromMaybe (error "Incomplete pattern") . pattern matchType ()
9590 operators =
9691 OperatorTable [ [ AssocL typeApp $ \f x -> f ++ " " ++ x ]
9792 , [ AssocR singleArgumentFunction $ \arg ret -> arg ++ " -> " ++ ret
98− , Wrap function $ \args ret -> "(" ++ intercalate ", " (map prettyPrintType args) ++ ") -> " ++ ret
9993 ]
10094 ]
src/Language/PureScript/Pretty/Values.hs+5−5
@@ -77,13 +77,13 @@ objectUpdate = mkPattern match
7777app :: Pattern () Value (String, Value)
7878app = mkPattern match
7979 where
80− match (App val args) = Just (intercalate "," (map prettyPrintValue args), val)
80+ match (App val arg) = Just (prettyPrintValue arg, val)
8181 match _ = Nothing
8282
83−lam :: Pattern () Value ([String], Value)
83+lam :: Pattern () Value (String, Value)
8484lam = mkPattern match
8585 where
86− match (Abs args val) = Just (map show args, val)
86+ match (Abs arg val) = Just (show arg, val)
8787 match _ = Nothing
8888
8989typed :: Pattern () Value (Type, Value)
@@ -127,8 +127,8 @@ prettyPrintValue = fromMaybe (error "Incomplete pattern") . pattern matchValue (
127127 operators =
128128 OperatorTable [ [ Wrap accessor $ \prop val -> val ++ "." ++ prop ]
129129 , [ Wrap objectUpdate $ \ps val -> val ++ "{ " ++ intercalate ", " ps ++ " }" ]
130− , [ Wrap app $ \args val -> val ++ "(" ++ args ++ ")" ]
131− , [ Split lam $ \args val -> "\\" ++ intercalate ", " args ++ " -> " ++ prettyPrintValue val ]
130+ , [ Wrap app $ \arg val -> val ++ "(" ++ arg ++ ")" ]
131+ , [ Split lam $ \arg val -> "\\" ++ arg ++ " -> " ++ prettyPrintValue val ]
132132 , [ Wrap ifThenElse $ \(th, el) cond -> cond ++ " ? " ++ prettyPrintValue th ++ " : " ++ prettyPrintValue el ]
133133 , [ Wrap typed $ \ty val -> val ++ " :: " ++ prettyPrintType ty ]
134134 , [ AssocR indexer (\index val -> val ++ " !! " ++ index) ]
src/Language/PureScript/Scope.hs+1−1
@@ -33,7 +33,7 @@ usedNames :: (Data d) => d -> [Ident]
3333usedNames val = nub $ everything (++) (mkQ [] namesV `extQ` namesS `extQ` namesB `extQ` namesJS) val
3434 where
3535 namesV :: Value -> [Ident]
36− namesV (Abs args _) = args
36+ namesV (Abs arg _) = [arg]
3737 namesV (Var (Qualified Nothing name)) = [name]
3838 namesV _ = []
3939 namesS :: Statement -> [Ident]
src/Language/PureScript/Sugar/CaseDeclarations.hs+7−11
@@ -48,27 +48,23 @@ toDecls :: [Declaration] -> Either String [Declaration]
4848toDecls d@[ValueDeclaration _ [] Nothing _] = return d
4949toDecls ds@(ValueDeclaration ident bs _ _ : _) = do
5050 let tuples = map toTuple ds
51− unless (all ((== map length bs) . map length . fst) tuples) $
51+ unless (all ((== length bs) . length . fst) tuples) $
5252 throwError $ "Argument list lengths differ in declaration " ++ show ident
5353 return [makeCaseDeclaration ident tuples]
5454toDecls ds = return ds
5555
56−toTuple :: Declaration -> ([[Binder]], (Maybe Guard, Value))
56+toTuple :: Declaration -> ([Binder], (Maybe Guard, Value))
5757toTuple (ValueDeclaration _ bs g val) = (bs, (g, val))
5858toTuple _ = error "Not a value declaration"
5959
60−makeCaseDeclaration :: Ident -> [([[Binder]], (Maybe Guard, Value))] -> Declaration
60+makeCaseDeclaration :: Ident -> [([Binder], (Maybe Guard, Value))] -> Declaration
6161makeCaseDeclaration ident alternatives =
6262 let
63− argPattern = map length . fst . head $ alternatives
64− args = take (sum argPattern) $ unusedNames (ident, alternatives)
63+ argPattern = length . fst . head $ alternatives
64+ args = take argPattern $ unusedNames (ident, alternatives)
6565 vars = map (\arg -> Var (Qualified Nothing arg)) args
66− binders = [ (join bs, g, val) | (bs, (g, val)) <- alternatives ]
67− value = foldr (\args' ret -> Abs args' ret) (Case vars binders) (rearrange argPattern args)
66+ binders = [ (bs, g, val) | (bs, (g, val)) <- alternatives ]
67+ value = foldr (\args' ret -> Abs args' ret) (Case vars binders) args
6868 in
6969 ValueDeclaration ident [] Nothing value
7070
71−rearrange :: [Int] -> [a] -> [[a]]
72−rearrange [] _ = []
73−rearrange (n:ns) xs = take n xs : rearrange ns (drop n xs)
74−
src/Language/PureScript/Sugar/DoNotation.hs+3−3
@@ -46,16 +46,16 @@ desugarDo = everywhereM (mkM replace)
4646 go [DoNotationValue val] = return val
4747 go (DoNotationValue val : rest) = do
4848 rest' <- go rest
49− return $ App (App bind [val]) [Abs [Ident "_"] rest']
49+ return $ App (App bind val) (Abs (Ident "_") rest')
5050 go [DoNotationBind _ _] = Left "Bind statement cannot be the last statement in a do block"
5151 go (DoNotationBind NullBinder val : rest) = go (DoNotationValue val : rest)
5252 go (DoNotationBind (VarBinder ident) val : rest) = do
5353 rest' <- go rest
54− return $ App (App bind [val]) [Abs [ident] rest']
54+ return $ App (App bind val) (Abs ident rest')
5555 go (DoNotationBind binder val : rest) = do
5656 rest' <- go rest
5757 let ident = head $ unusedNames rest'
58− return $ App (App bind [val]) [Abs [ident] (Case [Var (Qualified Nothing ident)] [([binder], Nothing, rest')])]
58+ return $ App (App bind val) (Abs ident (Case [Var (Qualified Nothing ident)] [([binder], Nothing, rest')]))
5959 go [DoNotationLet _ _] = Left "Let statement cannot be the last statement in a do block"
6060 go (DoNotationLet binder val : rest) = do
6161 rest' <- go rest
src/Language/PureScript/Sugar/Operators.hs+2−2
@@ -58,7 +58,7 @@ removeParens val = val
5858customOperatorTable :: M.Map (Qualified Ident) Fixity -> [[(Qualified Ident, Value -> Value -> Value, Associativity)]]
5959customOperatorTable fixities =
6060 let
61− applyUserOp name t1 t2 = App (App (Var name) [t1]) [t2]
61+ applyUserOp name t1 t2 = App (App (Var name) t1) t2
6262 userOps = map (\(name, Fixity a p) -> (name, applyUserOp name, p, a)) . M.toList $ fixities
6363 sorted = sortBy (compare `on` (\(_, _, p, _) -> p)) (userOps ++ builtIns)
6464 groups = groupBy ((==) `on` (\(_, _, p, _) -> p)) sorted
@@ -79,7 +79,7 @@ matchOperators moduleName ops val = G.everywhereM' (G.mkM parseChains) val
7979 bracketChain :: Chain -> Either String Value
8080 bracketChain = either (Left . show) Right . P.parse (P.buildExpressionParser opTable parseValue <* P.eof) "operator expression"
8181 opTable = map (map (\(name, f, a) -> P.Infix (P.try (matchOp moduleName name) >> return f) (toAssoc a))) ops
82− ++ [[P.Infix (P.try (parseOp >>= \ident -> return (\t1 t2 -> App (App (Var ident) [t1]) [t2]))) P.AssocLeft]]
82+ ++ [[P.Infix (P.try (parseOp >>= \ident -> return (\t1 t2 -> App (App (Var ident) t1) t2))) P.AssocLeft]]
8383
8484toAssoc :: Associativity -> P.Assoc
8585toAssoc Infixl = P.AssocLeft
src/Language/PureScript/Sugar/TypeClasses.hs+5−6
@@ -87,10 +87,8 @@ typeInstanceDictionaryDeclaration mn deps name ty decls = do
8787 memberNames <- mapM (memberToNameAndValue memberTypes) decls
8888 return $ ValueDeclaration entryName [] Nothing
8989 (TypedValue True
90− (Abs
91− (map (\n -> Ident ('_' : show n)) [1..length deps])
92− (ObjectLiteral memberNames))
93− (quantify (Function (map (\(pn, ty') -> TypeApp (TypeConstructor pn) ty') deps) (TypeApp (TypeConstructor name) ty)))
90+ (foldr Abs (ObjectLiteral memberNames) (map (\n -> Ident ('_' : show n)) [1..length deps]))
91+ (quantify (foldr (\t1 t2 -> TypeApp (TypeApp Function t1) t2) (TypeApp (TypeConstructor name) ty) (map (\(pn, ty') -> TypeApp (TypeConstructor pn) ty') deps)))
9492 )
9593 where
9694 memberToNameAndValue :: [(String, Type)] -> Declaration -> Desugar (String, Value)
@@ -99,7 +97,7 @@ typeInstanceDictionaryDeclaration mn deps name ty decls = do
9997 memberName <- mkDictionaryEntryName mn name ty ident
10098 return (identToJs ident, TypedValue False
10199 (if null deps then Var (Qualified Nothing memberName)
102− else App (Var (Qualified Nothing memberName)) (map (\n -> Var (Qualified Nothing (Ident ('_' : show n)))) [1..length deps]))
100+ else foldr App (Var (Qualified Nothing memberName)) (map (\n -> Var (Qualified Nothing (Ident ('_' : show n)))) [1..length deps]))
103101 (quantify memberType))
104102 memberToNameAndValue _ _ = error "Invalid declaration in type instance definition"
105103
@@ -139,10 +137,11 @@ typeToString _ String = return "string"
139137typeToString _ Number = return "number"
140138typeToString _ Boolean = return "boolean"
141139typeToString _ Array = return "array"
140+typeToString _ Function = return "function"
142141typeToString _ (TypeVar _) = return "var"
143142typeToString mn (TypeConstructor ty') = return $ qualifiedToString mn ty'
144143typeToString mn (TypeApp ty' (TypeVar _)) = typeToString mn ty'
145−typeToString a b = Left $ "Type class instance must be of the form T a1 ... an " ++ show (a, b)
144+typeToString _ _ = Left "Type class instance must be of the form T a1 ... an"
146145
147146-- |
148147-- Generate a name for a type class dictionary member, based on the module name, class name, type name and
src/Language/PureScript/TypeChecker.hs+2−2
@@ -51,7 +51,7 @@ addDataConstructor moduleName name args dctor maybeTy = do
5151 env <- getEnv
5252 dataConstructorIsNotDefined moduleName dctor
5353 let retTy = foldl TypeApp (TypeConstructor (Qualified (Just moduleName) name)) (map TypeVar args)
54− let dctorTy = maybe retTy (\ty -> Function [ty] retTy) maybeTy
54+ let dctorTy = maybe retTy (flip function retTy) maybeTy
5555 let polyType = mkForAll args dctorTy
5656 putEnv $ env { dataConstructors = M.insert (moduleName, dctor) (qualifyAllUnqualifiedNames moduleName env polyType, DataConstructor) (dataConstructors env) }
5757
@@ -231,7 +231,7 @@ typeCheckAll currentModule (d@(ImportDeclaration moduleName idents) : rest) = do
231231 constructs (TypeConstructor (Qualified (Just mn) pn')) pn
232232 = mn == moduleName && pn' == pn
233233 constructs (ForAll _ ty) pn = ty `constructs` pn
234− constructs (Function _ ty) pn = ty `constructs` pn
234+ constructs (TypeApp (TypeApp Function _) ty) pn = ty `constructs` pn
235235 constructs (TypeApp ty _) pn = ty `constructs` pn
236236 constructs fn _ = error $ "Invalid arguments to constructs: " ++ show fn
237237typeCheckAll moduleName (d@(TypeClassDeclaration _ _ _) : rest) = do
src/Language/PureScript/TypeChecker/Kinds.hs+1−6
@@ -125,12 +125,7 @@ infer (Object row) = do
125125 k <- infer row
126126 k ?= Row Star
127127 return Star
128−infer (Function args ret) = do
129− ks <- mapM infer args
130− k <- infer ret
131− k ?= Star
132− forM_ ks (?= Star)
133− return Star
128+infer Function = return $ FunKind Star $ FunKind Star Star
134129infer (TypeVar v) = do
135130 Just moduleName <- checkCurrentModule <$> get
136131 UnifyT . lift $ lookupTypeVariable moduleName (Qualified Nothing (ProperName v))
src/Language/PureScript/TypeChecker/Types.hs+46−44
@@ -99,11 +99,8 @@ unifyTypes t1 t2 = rethrow (\e -> "Error unifying type " ++ prettyPrintType t1 +
9999 unifyTypes' String String = return ()
100100 unifyTypes' Boolean Boolean = return ()
101101 unifyTypes' Array Array = return ()
102+ unifyTypes' Function Function = return ()
102103 unifyTypes' (Object row1) (Object row2) = row1 ?= row2
103− unifyTypes' (Function args1 ret1) (Function args2 ret2) = do
104− guardWith "Function applied to incorrect number of args" $ length args1 == length args2
105− zipWithM_ unifyTypes args1 args2
106− ret1 `unifyTypes` ret2
107104 unifyTypes' (TypeVar v1) (TypeVar v2) | v1 == v2 = return ()
108105 unifyTypes' (TypeConstructor c1) (TypeConstructor c2) = do
109106 env <- getEnv
@@ -235,14 +232,19 @@ entails moduleName context goal@(className, ty) = do
235232 , typeConstructorsAreEqual env moduleName className' (tcdClassName tcd)
236233 , subst <- maybeToList $ typeHeadsAreEqual moduleName env ty' (tcdInstanceType tcd)
237234 , args <- solveSubgoals env subst (tcdDependencies tcd) ]
235+ solveSubgoals :: Environment -> [(String, Type)] -> Maybe [(Qualified ProperName, Type)] -> [Maybe [Value]]
238236 solveSubgoals _ _ Nothing = return Nothing
239237 solveSubgoals env subst (Just subgoals) = do
240238 dict <- mapM (go env) (replaceAllTypeVars subst subgoals)
241239 return $ Just dict
242− mkDictionary fnName args = maybe id (flip App) args $ (Var fnName)
240+ mkDictionary :: Qualified Ident -> Maybe [Value] -> Value
241+ mkDictionary fnName Nothing = Var fnName
242+ mkDictionary fnName (Just dicts) = foldr (flip App) (Var fnName) dicts
243+ filterModule :: TypeClassDictionaryInScope -> Bool
243244 filterModule (TypeClassDictionaryInScope { tcdName = Qualified (Just mn) _ }) | mn == moduleName = True
244245 filterModule (TypeClassDictionaryInScope { tcdName = Qualified Nothing _ }) = True
245246 filterModule _ = False
247+ canonicalizeDictionary :: TypeClassDictionaryInScope -> Qualified Ident
246248 canonicalizeDictionary (TypeClassDictionaryInScope { tcdType = TCDRegular, tcdName = nm }) = nm
247249 canonicalizeDictionary (TypeClassDictionaryInScope { tcdType = TCDAlias nm }) = nm
248250
@@ -431,16 +433,16 @@ infer' (Accessor prop val) = do
431433 _ <- subsumes Nothing objTy (Object (RCons prop field rest))
432434 return $ TypedValue True (Accessor prop typed) field
433435 Just ty -> return $ TypedValue True (Accessor prop typed) ty
434−infer' (Abs args ret) = do
435− ts <- replicateM (length args) fresh
436+infer' (Abs arg ret) = do
437+ ty <- fresh
436438 Just moduleName <- checkCurrentModule <$> get
437− bindLocalVariables moduleName (zip args ts) $ do
439+ bindLocalVariables moduleName [(arg, ty)] $ do
438440 body@(TypedValue _ _ bodyTy) <- infer' ret
439− return $ TypedValue True (Abs args body) $ Function ts bodyTy
440−infer' (App f args) = do
441+ return $ TypedValue True (Abs arg body) $ function ty bodyTy
442+infer' (App f arg) = do
441443 f'@(TypedValue _ _ ft) <- infer f
442444 ret <- fresh
443− app <- checkFunctionApplication f' ft args ret
445+ app <- checkFunctionApplication f' ft arg ret
444446 return $ TypedValue True app ret
445447infer' (Var var) = do
446448 Just moduleName <- checkCurrentModule <$> get
@@ -450,7 +452,7 @@ infer' (Var var) = do
450452 ConstrainedType constraints _ -> do
451453 env <- getEnv
452454 dicts <- getTypeClassDictionaries
453− return $ TypedValue True (App (Var var) (map (flip TypeClassDictionary dicts) (qualifyAllUnqualifiedNames moduleName env constraints))) ty'
455+ return $ TypedValue True (foldr App (Var var) (map (flip TypeClassDictionary dicts) (qualifyAllUnqualifiedNames moduleName env constraints))) ty'
454456 _ -> return $ TypedValue True (Var var) ty'
455457infer' (Block ss) = do
456458 ret <- fresh
@@ -619,7 +621,7 @@ inferBinder val (UnaryBinder ctor binder) = do
619621 Just (ty, _) -> do
620622 fn <- replaceAllVarsWithUnknowns ty
621623 case fn of
622− Function [obj] ret -> do
624+ TypeApp (TypeApp Function obj) ret -> do
623625 _ <- subsumes Nothing val ret
624626 inferBinder obj binder
625627 _ -> throwError $ "Constructor " ++ show ctor ++ " is not a unary constructor"
@@ -792,7 +794,7 @@ check' val (ConstrainedType constraints ty) = do
792794 TypeClassDictionaryInScope name className instanceTy Nothing TCDRegular) (map (Qualified Nothing) dictNames)
793795 (qualifyAllUnqualifiedNames moduleName env constraints)) $
794796 check val ty
795− return $ Abs dictNames val'
797+ return $ foldr Abs val' dictNames
796798check' val u@(TUnknown _) = do
797799 val'@(TypedValue _ _ ty) <- infer val
798800 -- Don't unify an unknown with an inferred polytype
@@ -809,14 +811,13 @@ check' (Indexer index vals) ty = do
809811 index' <- check index Number
810812 vals' <- check vals (TypeApp Array ty)
811813 return $ Indexer index' vals'
812−check' (Abs args ret) (Function argTys retTy) = do
814+check' (Abs arg ret) (TypeApp (TypeApp Function argTy) retTy) = do
813815 Just moduleName <- checkCurrentModule <$> get
814− guardWith "Incorrect number of function arguments" (length args == length argTys)
815− ret' <- bindLocalVariables moduleName (zip args argTys) $ check ret retTy
816− return $ Abs args ret'
817−check' (App f args) ret = do
816+ ret' <- bindLocalVariables moduleName [(arg, argTy)] $ check ret retTy
817+ return $ Abs arg ret'
818+check' (App f arg) ret = do
818819 f'@(TypedValue _ _ ft) <- infer f
819− app <- checkFunctionApplication f' ft args ret
820+ app <- checkFunctionApplication f' ft arg ret
820821 return $ app
821822check' v@(Var var) ty = do
822823 Just moduleName <- checkCurrentModule <$> get
@@ -918,42 +919,43 @@ checkProperties ps row lax = let (ts, r') = rowToList row in go ps ts r' where
918919-- |
919920-- Check the type of a function application, rethrowing errors to provide a better error message
920921--
921−checkFunctionApplication :: Value -> Type -> [Value] -> Type -> UnifyT Check Value
922−checkFunctionApplication fn fnTy args ret = rethrow errorMessage $ checkFunctionApplication' fn fnTy args ret
922+checkFunctionApplication :: Value -> Type -> Value -> Type -> UnifyT Check Value
923+checkFunctionApplication fn fnTy arg ret = rethrow errorMessage $ checkFunctionApplication' fn fnTy arg ret
923924 where
924925 errorMessage msg = "Error applying function of type "
925926 ++ prettyPrintType fnTy
926− ++ " to arguments " ++ intercalate ", " (map prettyPrintValue args)
927+ ++ " to argument " ++ prettyPrintValue arg
927928 ++ ":\n" ++ msg
928929
929930-- |
930931-- Check the type of a function application
931932--
932−checkFunctionApplication' :: Value -> Type -> [Value] -> Type -> UnifyT Check Value
933−checkFunctionApplication' fn (Function argTys retTy) args ret = do
934− guardWith "Incorrect number of function arguments" (length args == length argTys)
935− args' <- zipWithM check args argTys
933+checkFunctionApplication' :: Value -> Type -> Value -> Type -> UnifyT Check Value
934+checkFunctionApplication' fn (TypeApp (TypeApp Function argTy) retTy) arg ret = do
935+ arg' <- check arg argTy
936936 _ <- subsumes Nothing retTy ret
937− return $ App fn args'
938−checkFunctionApplication' fn (ForAll ident ty) args ret = do
937+ return $ App fn arg'
938+checkFunctionApplication' fn (ForAll ident ty) arg ret = do
939939 replaced <- replaceVarWithUnknown ident ty
940− checkFunctionApplication fn replaced args ret
941−checkFunctionApplication' fn u@(TUnknown _) args ret = do
942− args' <- mapM (\arg -> infer arg >>= \(TypedValue _ v t) -> TypedValue True v <$> replaceAllVarsWithUnknowns t) args
943− let tys = map (\(TypedValue _ _ t) -> t) args'
944− u ?= Function tys ret
945− return $ App fn args'
946−checkFunctionApplication' fn (SaturatedTypeSynonym name tyArgs) args ret = do
940+ checkFunctionApplication fn replaced arg ret
941+checkFunctionApplication' fn u@(TUnknown _) arg ret = do
942+ arg' <- do
943+ TypedValue _ v t <- infer arg
944+ TypedValue True v <$> replaceAllVarsWithUnknowns t
945+ let ty = (\(TypedValue _ _ t) -> t) arg'
946+ u ?= function ty ret
947+ return $ App fn arg'
948+checkFunctionApplication' fn (SaturatedTypeSynonym name tyArgs) arg ret = do
947949 ty <- expandTypeSynonym name tyArgs
948− checkFunctionApplication fn ty args ret
949−checkFunctionApplication' fn (ConstrainedType constraints fnTy) args ret = do
950+ checkFunctionApplication fn ty arg ret
951+checkFunctionApplication' fn (ConstrainedType constraints fnTy) arg ret = do
950952 env <- getEnv
951953 dicts <- getTypeClassDictionaries
952954 Just moduleName <- checkCurrentModule <$> get
953− checkFunctionApplication' (App fn (map (flip TypeClassDictionary dicts) (qualifyAllUnqualifiedNames moduleName env constraints))) fnTy args ret
954−checkFunctionApplication' _ fnTy args ret = throwError $ "Applying a function of type "
955+ checkFunctionApplication' (foldr App fn (map (flip TypeClassDictionary dicts) (qualifyAllUnqualifiedNames moduleName env constraints))) fnTy arg ret
956+checkFunctionApplication' _ fnTy arg ret = throwError $ "Applying a function of type "
955957 ++ prettyPrintType fnTy
956− ++ " to argument(s) " ++ intercalate ", " (map prettyPrintValue args)
958+ ++ " to argument(s) " ++ prettyPrintValue arg
957959 ++ " does not yield a value of type " ++ prettyPrintType ret ++ "."
958960
959961-- |
@@ -975,8 +977,8 @@ subsumes' :: Maybe Value -> Type -> Type -> UnifyT Check (Maybe Value)
975977subsumes' val (ForAll ident ty1) ty2 = do
976978 replaced <- replaceVarWithUnknown ident ty1
977979 subsumes val replaced ty2
978−subsumes' val (Function args1 ret1) (Function args2 ret2) = do
979− zipWithM_ (subsumes Nothing) args2 args1
980+subsumes' val (TypeApp (TypeApp Function arg1) ret1) (TypeApp (TypeApp Function arg2) ret2) = do
981+ subsumes Nothing arg2 arg1
980982 subsumes Nothing ret1 ret2
981983 return val
982984subsumes' (Just val) (ConstrainedType constraints ty1) ty2 = do
@@ -984,7 +986,7 @@ subsumes' (Just val) (ConstrainedType constraints ty1) ty2 = do
984986 dicts <- getTypeClassDictionaries
985987 Just moduleName <- checkCurrentModule <$> get
986988 _ <- subsumes' Nothing ty1 ty2
987− return . Just $ App val (map (flip TypeClassDictionary dicts) (qualifyAllUnqualifiedNames moduleName env constraints))
989+ return . Just $ foldr App val (map (flip TypeClassDictionary dicts) (qualifyAllUnqualifiedNames moduleName env constraints))
988990subsumes' val ty1 ty2 = do
989991 ty1 ?= ty2
990992 return val
src/Language/PureScript/Types.hs+8−13
@@ -55,7 +55,7 @@ data Type
5555 -- |
5656 -- A function, with zero or more arguments
5757 --
58− | Function [Type] Type
58+ | Function
5959 -- |
6060 -- A named type variable
6161 --
@@ -93,6 +93,12 @@ data Type
9393 --
9494 | RCons String Type Type deriving (Show, Eq, Data, Typeable)
9595
96+-- |
97+-- Smart constructor for function types
98+--
99+function :: Type -> Type -> Type
100+function t1 t2 = TypeApp (TypeApp Function t1) t2
101+
96102-- |
97103-- Convert a row to a list of pairs of labels and types
98104--
@@ -113,18 +119,7 @@ rowFromList ((name, t):ts, r) = RCons name t (rowFromList (ts, r))
113119--
114120isMonoType :: Type -> Bool
115121isMonoType (ForAll _ _) = False
116−isMonoType ty = isPolyType ty
117−
118−-- |
119−-- Check whather a type is a valid polytype
120−--
121−isPolyType :: Type -> Bool
122−isPolyType (Object ps) = all isPolyType (map snd . fst $ rowToList ps)
123−isPolyType (Function args ret) = all isPolyType args && isPolyType ret
124−isPolyType (TypeApp t1 t2) = isMonoType t1 && isMonoType t2
125−isPolyType (SaturatedTypeSynonym _ args) = all isPolyType args
126−isPolyType (ForAll _ ty) = isPolyType ty
127−isPolyType _ = True
122+isMonoType ty = True
128123
129124-- |
130125-- Universally quantify a type
src/Language/PureScript/Values.hs+2−2
@@ -190,11 +190,11 @@ data Value
190190 -- |
191191 -- Function introduction
192192 --
193− | Abs [Ident] Value
193+ | Abs Ident Value
194194 -- |
195195 -- Function application
196196 --
197− | App Value [Value]
197+ | App Value Value
198198 -- |
199199 -- Variable
200200 --