@@ -68,7 +68,7 @@ moduleToCpp env (Module _ mn imps _ foreigns decls) = do
6868 delete (ModuleName [ProperName C.prim]) . (\\ [mn]) $
6969 imps
7070 let cppImports' = "PureScript" : cppImports
71− cppDecls <- concat <$> mapM bindToCpp decls
71+ cppDecls <- concat <$> mapM (bindToCpp [CppTopLevel]) decls
7272 optimized <- traverse optimize cppDecls
7373 let moduleHeader =
7474 fileBegin mn "HH" ++
@@ -101,10 +101,10 @@ moduleToCpp env (Module _ mn imps _ foreigns decls) = do
101101 -- Generate code in the simplified C++1x intermediate representation for a declaration
102102 --
103103 -------------------------------------------------------------------------------------------------
104− bindToCpp :: Bind Ann -> m [Cpp]
104+ bindToCpp :: [CppValueQual] -> Bind Ann -> m [Cpp]
105105 -------------------------------------------------------------------------------------------------
106− bindToCpp (NonRec ident val) = return <$> declToCpp [] ident val
107− bindToCpp (Rec vals) = forM vals (uncurry $ declToCpp [CppRecursive])
106+ bindToCpp qs (NonRec ident val) = return <$> declToCpp qs ident val
107+ bindToCpp qs (Rec vals) = forM vals (uncurry $ declToCpp (CppRecursive:qs))
108108
109109 -- |
110110 -- Desugar a declaration into a variable introduction or named function
@@ -177,6 +177,33 @@ moduleToCpp env (Module _ mn imps _ foreigns decls) = do
177177 | otherwise = fullyConstructed
178178 fullyConstructed = [CppReturn (CppDataLiteral (CppStringLiteral name : (CppVar <$> fields')))]
179179
180+ declToCpp qs ident e@(App (_, _, Just ty, _) _ _)
181+ | CppTopLevel `elem` qs,
182+ count <- countArgs ty,
183+ count > 0 = do
184+ argNames <- replicateM count freshName
185+ block <- flip (foldl (\fn a -> CppApp fn [a])) (CppVar <$> argNames) <$> valueToCpp e
186+ return $ CppFunction
187+ (identToCpp ident)
188+ [(head argNames, Just $ CppAny [CppConst, CppRef])]
189+ (Just $ CppAny [])
190+ []
191+ (asReturnBlock $ curried (tail argNames) block)
192+ where
193+ curried :: [String] -> Cpp -> Cpp
194+ curried args vals = foldl (\val arg -> CppLambda
195+ [CppCaptureAll]
196+ [(arg, Just $ CppAny [CppConst, CppRef])]
197+ (Just $ CppAny [])
198+ (asReturnBlock val)
199+ ) vals args
200+ countArgs :: T.Type -> Int
201+ countArgs = go 0
202+ where
203+ go argcnt (T.ForAll _ t _) = go argcnt t
204+ go argcnt (T.TypeApp (T.TypeApp fn _) t) | fn == E.tyFunction = go (argcnt + 1) t
205+ go argcnt _ = argcnt
206+
180207 declToCpp _ ident val = do
181208 val' <- valueToCpp val
182209 return $
@@ -351,7 +378,7 @@ moduleToCpp env (Module _ mn imps _ foreigns decls) = do
351378 bindersToCpp maybeSpan ty binders vals
352379
353380 valueToCpp (Let _ ds val) = do
354− ds' <- concat <$> mapM bindToCpp ds
381+ ds' <- concat <$> mapM (bindToCpp []) ds
355382 ret <- valueToCpp val
356383 let ds'' = tco defaultOptions <$> ds'
357384 let rs = if hasRecursion ds''