@@ -26,27 +26,31 @@ import Language.PureScript.Scope
2626desugarDo :: (Data d) => d -> Either String d
2727desugarDo = everywhereM (mkM replace)
2828 where
29+ prelude :: ModuleName
30+ prelude = ModuleName (ProperName "Prelude")
31+ ret :: Value
32+ ret = Var (Qualified (Just prelude) (Ident "ret"))
33+ bind :: Value
34+ bind = Var (Qualified (Just prelude) (Op ">>="))
2935 replace :: Value -> Either String Value
30− replace (Do monad els) = go monad els
36+ replace (Do els) = go els
3137 replace other = return other
32− go :: Value -> [DoNotationElement] -> Either String Value
33− go _ [] = error "The impossible happened in desugarDo"
34− go monad [DoNotationReturn val] = return $ App (Accessor "ret" monad) [val]
35− go _ (DoNotationReturn _ : _) = Left "Return statement must be the last statement in a do block"
36− go _ [DoNotationValue val] = return val
37− go monad (DoNotationValue val : rest) = do
38− rest' <- go monad rest
39− return $ App (App (Accessor "bind" monad) [val]) [Abs [Ident "_"] rest']
40− go _ [DoNotationBind _ _] = Left "Bind statement cannot be the last statement in a do block"
41− go monad (DoNotationBind NullBinder val : rest) = go monad (DoNotationValue val : rest)
42− go monad (DoNotationBind (VarBinder ident) val : rest) = do
43− rest' <- go monad rest
44− return $ App (App (Accessor "bind" monad) [val]) [Abs [ident] rest']
45− go monad (DoNotationBind binder val : rest) = do
46− rest' <- go monad rest
38+ go :: [DoNotationElement] -> Either String Value
39+ go [] = error "The impossible happened in desugarDo"
40+ go [DoNotationValue val] = return val
41+ go (DoNotationValue val : rest) = do
42+ rest' <- go rest
43+ return $ App (App bind [val]) [Abs [Ident "_"] rest']
44+ go [DoNotationBind _ _] = Left "Bind statement cannot be the last statement in a do block"
45+ go (DoNotationBind NullBinder val : rest) = go (DoNotationValue val : rest)
46+ go (DoNotationBind (VarBinder ident) val : rest) = do
47+ rest' <- go rest
48+ return $ App (App bind [val]) [Abs [ident] rest']
49+ go (DoNotationBind binder val : rest) = do
50+ rest' <- go rest
4751 let ident = head $ unusedNames rest'
48− return $ App (App (Accessor "bind" monad) [val]) [Abs [ident] (Case [Var (Qualified Nothing ident)] [([binder], Nothing, rest')])]
49− go _ [DoNotationLet _ _] = Left "Let statement cannot be the last statement in a do block"
50− go monad (DoNotationLet binder val : rest) = do
51− rest' <- go monad rest
52+ return $ App (App bind [val]) [Abs [ident] (Case [Var (Qualified Nothing ident)] [([binder], Nothing, rest')])]
53+ go [DoNotationLet _ _] = Left "Let statement cannot be the last statement in a do block"
54+ go (DoNotationLet binder val : rest) = do
55+ rest' <- go rest
5256 return $ Case [val] [([binder], Nothing, rest')]