欢迎访问宙启技术站
智能推送

通过Haskell构建一个计算器应用程序

发布时间:2023-12-10 01:04:12

Haskell是一种函数式编程语言,非常适合用于构建计算器应用程序。下面是使用Haskell构建计算器应用程序的示例,包含基本的四则运算和括号支持。

首先,我们定义一个数据类型Expr来表示一个表达式。它可以是一个数字(表示常量),可以是两个表达式的运算结果(加法、减法、乘法、除法),或者可以是一个表达式加上括号。

data Expr = Const Double | Add Expr Expr | Sub Expr Expr | Mul Expr Expr | Div Expr Expr | Brackets Expr

接下来,我们定义一个求值函数eval,用于计算表达式的值。该函数通过递归地处理表达式的不同部分,最终计算出整个表达式的结果。

eval :: Expr -> Double
eval (Const x) = x
eval (Add e1 e2) = eval e1 + eval e2
eval (Sub e1 e2) = eval e1 - eval e2
eval (Mul e1 e2) = eval e1 * eval e2
eval (Div e1 e2) = eval e1 / eval e2
eval (Brackets e) = eval e

接下来,我们定义一个解析函数parse,用于将输入的字符串解析成表达式。该函数使用递归下降的方式解析字符串,将其转换为一个表达式。

parse :: String -> Maybe Expr
parse input = case parseExpr input of
               Just (expr, "") -> Just expr
               _ -> Nothing

parseExpr :: String -> Maybe (Expr, String)
parseExpr input = parseAddSub input

parseAddSub :: String -> Maybe (Expr, String)
parseAddSub input = case parseMulDiv input of
                     Just (expr, rest) -> parseAddSubRest expr rest
                     Nothing -> Nothing

parseAddSubRest :: Expr -> String -> Maybe (Expr, String)
parseAddSubRest expr ('+':rest) = do
                                   (expr2, rest2) <- parseMulDiv rest
                                   parseAddSubRest (Add expr expr2) rest2
parseAddSubRest expr ('-':rest) = do
                                   (expr2, rest2) <- parseMulDiv rest
                                   parseAddSubRest (Sub expr expr2) rest2
parseAddSubRest expr input = Just (expr, input)

parseMulDiv :: String -> Maybe (Expr, String)
parseMulDiv input = case parseTerm input of
                     Just (expr, rest) -> parseMulDivRest expr rest
                     Nothing -> Nothing

parseMulDivRest :: Expr -> String -> Maybe (Expr, String)
parseMulDivRest expr ('*':rest) = do
                                   (expr2, rest2) <- parseTerm rest
                                   parseMulDivRest (Mul expr expr2) rest2
parseMulDivRest expr ('/':rest) = do
                                   (expr2, rest2) <- parseTerm rest
                                   parseMulDivRest (Div expr expr2) rest2
parseMulDivRest expr input = Just (expr, input)

parseTerm :: String -> Maybe (Expr, String)
parseTerm ('(':rest) = do
                       (expr, rest2) <- parseExpr rest
                       case rest2 of
                         (')':rest3) -> Just (Brackets expr, rest3)
                         _ -> Nothing
parseTerm input = parseNumber input

parseNumber :: String -> Maybe (Expr, String)
parseNumber input = case reads input of
                     [(x, rest)] -> Just (Const x, rest)
                     _ -> Nothing

最后,我们定义一个计算器函数calculate,将用户输入的字符串进行解析和求值,并返回结果(如果输入的表达式无效,则返回Nothing)。

calculate :: String -> Maybe Double
calculate input = case parse input of
                   Just expr -> Just (eval expr)
                   Nothing -> Nothing

现在,我们可以使用calculate函数进行计算了,下面是一些使用示例:

calculate "2 + 3 * 4" -- 返回Just 14.0
calculate "(2 + 3) * 4" -- 返回Just 20.0
calculate "10 / 2 + 3" -- 返回Just 8.0
calculate "10 / (2 + 3)" -- 返回Just 2.0
calculate "10 / 0" -- 返回Nothing(除零错误)
calculate "abc" -- 返回Nothing(无效表达式)

通过以上示例,我们可以看到使用Haskell构建一个计算器应用程序非常简洁而且功能强大。你可以根据自己的需求扩展它,添加更多的功能,如支持更复杂的运算、函数、变量等。祝你在使用Haskell构建计算器应用程序上取得成功!