diff --git a/purescript.cabal b/purescript.cabal
--- a/purescript.cabal
+++ b/purescript.cabal
@@ -1,5 +1,5 @@
 name: purescript
-version: 0.4.12.1
+version: 0.4.13
 cabal-version: >=1.8
 build-type: Custom
 license: MIT
diff --git a/src/Language/PureScript/Declarations.hs b/src/Language/PureScript/Declarations.hs
--- a/src/Language/PureScript/Declarations.hs
+++ b/src/Language/PureScript/Declarations.hs
@@ -378,7 +378,7 @@
   -- |
   -- A let statement, i.e. a pure value with a binder
   --
-  | DoNotationLet Binder Value
+  | DoNotationLet [Declaration]
   -- |
   -- A do notation element with source position information
   --
diff --git a/src/Language/PureScript/Optimizer/Unused.hs b/src/Language/PureScript/Optimizer/Unused.hs
--- a/src/Language/PureScript/Optimizer/Unused.hs
+++ b/src/Language/PureScript/Optimizer/Unused.hs
@@ -24,12 +24,14 @@
 import Language.PureScript.Optimizer.Common
 
 removeUnusedVariables :: JS -> JS
-removeUnusedVariables = everywhere (mkT $ removeFromBlock go)
+removeUnusedVariables = everywhere (mkT $ removeFromBlock withBlock)
   where
-  go :: [JS] -> [JS]
-  go [] = []
-  go (JSVariableIntroduction var _ : sts) | not (isUsed var sts) = go sts
-  go (s:sts) = s : go sts
+  withBlock :: [JS] -> [JS]
+  withBlock sts = go sts sts
+  go :: [JS] -> [JS] -> [JS]
+  go _ [] = []
+  go sts (JSVariableIntroduction var _ : rest) | not (isUsed var sts) = go sts rest
+  go sts (s : rest) = s : go sts rest
 
 removeCodeAfterReturnStatements :: JS -> JS
 removeCodeAfterReturnStatements = everywhere (mkT $ removeFromBlock go)
diff --git a/src/Language/PureScript/Parser/Declarations.hs b/src/Language/PureScript/Parser/Declarations.hs
--- a/src/Language/PureScript/Parser/Declarations.hs
+++ b/src/Language/PureScript/Parser/Declarations.hs
@@ -306,8 +306,7 @@
   Do <$> C.mark (P.many (C.same *> C.mark parseDoNotationElement))
 
 parseDoNotationLet :: P.Parsec String ParseState DoNotationElement
-parseDoNotationLet = DoNotationLet <$> (C.reserved "let" *> C.indented *> parseBinder)
-                                   <*> (C.indented *> C.reservedOp "=" *> parseValue)
+parseDoNotationLet = DoNotationLet <$> (C.reserved "let" *> C.indented *> C.mark (P.many1 (C.same *> parseLocalDeclaration)))
 
 parseDoNotationBind :: P.Parsec String ParseState DoNotationElement
 parseDoNotationBind = DoNotationBind <$> parseBinder <*> (C.indented *> C.reservedOp "<-" *> parseValue)
diff --git a/src/Language/PureScript/Pretty/Values.hs b/src/Language/PureScript/Pretty/Values.hs
--- a/src/Language/PureScript/Pretty/Values.hs
+++ b/src/Language/PureScript/Pretty/Values.hs
@@ -104,12 +104,10 @@
     , return " <- "
     , prettyPrintValue' val
     ]
-prettyPrintDoNotationElement (DoNotationLet binder val) =
+prettyPrintDoNotationElement (DoNotationLet ds) =
   fmap concat $ sequence
     [ return "let "
-    , prettyPrintBinder' binder
-    , return " = "
-    , prettyPrintValue' val
+    , withIndent $ prettyPrintMany prettyPrintDeclaration ds
     ]
 prettyPrintDoNotationElement (PositionedDoNotationElement _ el) = prettyPrintDoNotationElement el
 
diff --git a/src/Language/PureScript/Sugar/DoNotation.hs b/src/Language/PureScript/Sugar/DoNotation.hs
--- a/src/Language/PureScript/Sugar/DoNotation.hs
+++ b/src/Language/PureScript/Sugar/DoNotation.hs
@@ -59,8 +59,8 @@
     rest' <- go rest
     let ident = head $ unusedNames rest'
     return $ App (App bind val) (Abs (Left ident) (Case [Var (Qualified Nothing ident)] [CaseAlternative [binder] Nothing rest']))
-  go [DoNotationLet _ _] = Left $ mkErrorStack "Let statement cannot be the last statement in a do block" Nothing
-  go (DoNotationLet binder val : rest) = do
+  go [DoNotationLet _] = Left $ mkErrorStack "Let statement cannot be the last statement in a do block" Nothing
+  go (DoNotationLet ds : rest) = do
     rest' <- go rest
-    return $ Case [val] [CaseAlternative [binder] Nothing rest']
+    return $ Let ds rest'
   go (PositionedDoNotationElement pos el : rest) = PositionedValue pos <$> go (el : rest)
