subs (LetExpr name old_def old_expr) old new = do
    new_def <- subs old_def old new
    new_expr <- subs old_expr old new
    return $ LetExpr name new_def new_expr
{- OPT (subs old_def old new) >>= 
    (\new_def -> (subs old_expr old new) >>= 
        (\new_expr -> return $ LetExpr name new_def new_expr)
    )-}
subs (LetExpr name old_def old_expr) old new = do
    new_def <- subs old_def old new
    new_expr <- subs old_expr old new
    return $ LetExpr name new_def new_expr
{- OPT (subs old_def old new) >>= 
    (\new_def -> (subs old_expr old new) >>= 
        (\new_expr -> return $ LetExpr name new_def new_expr)
    )-}
subs (LetExpr name old_def old_expr) old new = do
    new_def <- subs old_def old new
    new_expr <- subs old_expr old new
    return $ LetExpr name new_def new_expr
{- OPT (subs old_def old new) >>= 
    (\new_def -> (subs old_expr old new) >>= 
        (\new_expr -> return $ LetExpr name new_def new_expr)
    )-}