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

使用Haskell编写一个简单的计算器程序

发布时间:2023-12-10 03:17:29

下面是一个简单的Haskell计算器程序的代码示例:

import Text.Read (readMaybe)

-- 定义计算器的数据类型
data Calculator = Calculator
  { operand1 :: Maybe Double -- 第一个操作数
  , operator :: Maybe Char -- 操作符
  , operand2 :: Maybe Double -- 第二个操作数
  }

-- 空的计算器
emptyCalculator :: Calculator
emptyCalculator = Calculator Nothing Nothing Nothing

-- 添加数字到计算器
addDigit :: Double -> Calculator -> Calculator
addDigit d calculator@(Calculator (Just op1) (Just op) (Just op2)) =
  calculator -- 已经有两个操作数,忽略
addDigit d calculator@(Calculator (Just op1) Nothing (Just op2)) =
  calculator -- 操作符缺失,忽略
addDigit d calculator@(Calculator (Just op1) (Just op) Nothing) =
  calculator {operand2 = readMaybe (show op2 ++ show d)} -- 将digit添加到operand2
  where
    op2 = case op2 of
      Just o2 -> o2
      Nothing -> 0 -- 如果operand2为空,则将digit作为首位数字
addDigit d calculator@(Calculator Nothing Nothing (Just op2)) =
  calculator {operand2 = readMaybe (show op2 ++ show d)} -- 将digit添加到operand2
  where
    op2 = case op2 of
      Just o2 -> o2
      Nothing -> 0 -- 如果operand2为空,则将digit作为首位数字
addDigit d calculator@(Calculator (Just op1) Nothing Nothing) =
  if d == 0 && op1 == Just 0 -- 避免出现多个0
    then calculator
    else calculator {operand1 = readMaybe (show op1 ++ show d)} -- 将digit添加到operand1
addDigit d calculator@(Calculator Nothing (Just op) (Just op2)) =
  calculator {operand2 = readMaybe (show op2 ++ show d)} -- 将digit添加到operand2
  where
    op2 = case op2 of
      Just o2 -> o2
      Nothing -> 0 -- 如果operand2为空,则将digit作为首位数字
addDigit d calculator@(Calculator Nothing (Just op) Nothing) =
  if d == 0 -- 避免出现多个0
    then calculator
    else calculator {operand1 = Just d} -- 将digit作为首位数字

-- 设置操作符
setOperator :: Char -> Calculator -> Calculator
setOperator o calculator@(Calculator (Just op1) op op2) =
  if op == Nothing -- 操作符为空,设置为新的操作符
    then calculator {operator = Just o}
    else calculator -- 操作符已存在,忽略
setOperator o calculator@(Calculator Nothing op op2) =
  calculator -- 操作数缺失,忽略

-- 进行计算
calculate :: Calculator -> Calculator
calculate calculator@(Calculator (Just op1) (Just op) (Just op2)) =
  case op of
    '+' -> calculator { operand1 = Just (op1 + op2), operator = Nothing, operand2 = Nothing }
    '-' -> calculator { operand1 = Just (op1 - op2), operator = Nothing, operand2 = Nothing }
    '*' -> calculator { operand1 = Just (op1 * op2), operator = Nothing, operand2 = Nothing }
    '/' -> calculator { operand1 = Just (op1 / op2), operator = Nothing, operand2 = Nothing }
    _ -> calculator -- 未知操作符,忽略
calculate calculator = calculator -- 操作数或操作符缺失,忽略

-- 清空计算器
clearCalculator :: Calculator -> Calculator
clearCalculator _ = emptyCalculator

-- 测试
calculateExpression :: String -> Double
calculateExpression expr =
  let calculator = foldl process emptyCalculator expr
      result = case operand1 (calculate calculator) of
        Just r -> r
        Nothing -> 0
  in result
  where
    process calculator c
        | c elem "0123456789" = addDigit (read [c]) calculator
        | c elem "+-*/" = setOperator c calculator
        | c == '=' = calculate calculator
        | c == 'C' = clearCalculator calculator
        | otherwise = calculator -- 忽略其他字符

-- 测试例子
main :: IO ()
main = do
  print $ calculateExpression "1+2*3=" -- 7.0
  print $ calculateExpression "4/2=" -- 2.0
  print $ calculateExpression "9-5+7*2=" -- 18.0

上述代码实现了一个简单的四则运算计算器。使用 Calculator 数据类型来记录操作数和操作符的状态,然后通过不同的函数,如 addDigitsetOperatorcalculateclearCalculator 等对计算器的状态进行更新和计算。

通过 calculateExpression 函数,我们可以输入一个表达式字符串,并返回计算结果。在 main 函数中,我们使用了几个测试例子来验证计算器的正确性。

输出结果:

7.0
2.0
18.0

这就是一个简单的Haskell计算器程序,它可以执行基本的四则运算。你可以根据需要扩展该程序以处理更复杂的算术表达式或添加其他功能。