【发布时间】:2014-01-19 01:13:24
【问题描述】:
我对 Haskell 很陌生,我需要制作一个可以工作的计算器,它可以回答以下表达式:2+3*(5+12) 我有一些东西可以或多或少地计算,但我的操作顺序有问题。我不知道该怎么做。这是我的代码:
import Text.Regex.Posix
import Data.Maybe
oblicz :: String -> Double
oblicz str = eval (Nothing, None) $ map convertToExpression $ ( tokenize str )
eval :: (Maybe Double,Expression)->[Expression]->Double
eval (Nothing, _) ((Variable v):reszta) = eval (Just v, None) reszta
eval (Just aktualnyWynik, None) ((Operator o):reszta) = eval ((Just aktualnyWynik), (Operator o)) reszta
eval (Just aktualnyWynik, (Operator o)) ((Variable v):reszta) = eval (Just $ o aktualnyWynik v , None) reszta
eval (aktualnyWynik, operator) (LeftParenthesis:reszta)
= eval (aktualnyWynik, operator) ((Variable (eval (Nothing, None) reszta)):(getPartAfterParentheses reszta))
eval (Just aktualnyWynik, _) [] = aktualnyWynik
eval (Just aktualnyWynik, _) (RightParenthesis:_) = aktualnyWynik
data Expression = Operator (Double->Double->Double)
| Variable Double
| LeftParenthesis
| RightParenthesis
| None
tokenize :: String -> [String]
tokenize expression = getAllTextMatches(expression =~ "([0-9]+|\\(|\\)|\\+|-|%|/|\\*)" :: AllTextMatches [] String)
convertToExpression :: String -> Expression
convertToExpression "-" = Operator (-)
convertToExpression "+" = Operator (+)
convertToExpression "*" = Operator (*)
convertToExpression "/" = Operator (/)
convertToExpression "(" = LeftParenthesis
convertToExpression ")" = RightParenthesis
convertToExpression variable = Variable (read variable)
getPartAfterParentheses :: [Expression] -> [Expression]
getPartAfterParentheses [] = []
getPartAfterParentheses (RightParenthesis:expressionsList) = expressionsList
getPartAfterParentheses (LeftParenthesis:expressionsList) = getPartAfterParentheses (getPartAfterParentheses expressionsList)
getPartAfterParentheses (expression:expressionsList) = getPartAfterParentheses expressionsList
我想也许我可以创建两个堆栈 - 一个带有数字,一个带有运算符。在阅读表达式时,我可以将数字压入一个堆栈,将运算符压入另一个堆栈。当它是一个运算符时,我会检查堆栈上是否已经有东西,如果有检查我是否应该从堆栈中弹出它并进行数学运算 - 就像在 onp 表示法中一样。
不幸的是,正如我所说,我对 haskell 还很陌生,不知道如何写这篇文章。
任何提示或帮助都会很好:)
【问题讨论】:
-
"这个问题似乎离题了,因为它缺乏足够的信息来诊断问题。更详细地描述您的问题或在问题本身中包含一个最小示例。 "
-
你能提供一些示例输入和输出吗?输出与您的预期有何不同?
-
LeftParenthesis不是Expression,它只是一个解析标记。一旦您意识到这一点,您将看到表达式需要以不同的方式捕获(例如,下面的答案中的树),其中操作的优先级将以相当简单的方式出现。
标签: haskell stack calculator