-- | Parses a function declaration: The func keyword, followed by a function
-- name, a parenthesized potentially empty list of parameter fields
-- (comma-separated list of identifiers then a type) separated by commas, an
-- optional return type and a block.
funDecl :: Parser SrcAnnFunDecl
funDecl = do
    name <- (kwFunc >>= noSemiP) >> (identifier >>= noSemiP)
    params <- (parens $ (field >>= noSemiP) `sepBy` comma) >>= noSemiP
    ret <- optional (type_ >>= noSemiP)
    b <- blockP >>= requireSemiP

    pure $ FunDecl name (concatMap (uncurry distTuple) params) ret b
funDecl :: Parser SrcAnnFunDecl
funDecl = do
    name <- (kwFunc >>= noSemiP) >> (identifier >>= noSemiP)
    params <- (parens $ (field >>= noSemiP) `sepBy` comma) >>= noSemiP
    ret <- optional (type_ >>= noSemiP)
    b <- blockP >>= requireSemiP

    pure $ FunDecl name (concatMap (uncurry distTuple) params) ret b
funDecl = do
    name <- (kwFunc >>= noSemiP) >> (identifier >>= noSemiP)
    params <- (parens $ (field >>= noSemiP) `sepBy` comma) >>= noSemiP
    ret <- optional (type_ >>= noSemiP)
    b <- blockP >>= requireSemiP

    pure $ FunDecl name (concatMap (uncurry distTuple) params) ret b