我需要编写一个代码,该代码评估操作字符串并输出该字符串的结果整数。我写了一些东西,但是没用,需要一些帮助。我需要使用折叠,因为它比较容易,但是我确定出了什么问题。这是在Haskell上,并使用Emacs。
evalExpr :: String -> Int
evalExpr xs = foldl 0 xs where
f v x | x == "+" = (+) v
| x == "-" = (-) v
| x == " " = 0
| otherwise = read v :: Int
例如:
evalExpr“ 2 + 4 + 5-8”
输出应为:3
evalExpr“”
输出应为:0
这是因为它应该从左到右读取字符串。
答案 0 :(得分:1)
您可以按照@ 5ndG的建议进行操作。但是,要评估操作字符串,使用parsec
是更好的方法。这是您的情况的示例:
module EvalExpr where
-- You need parsec to do parsing work, and the following are just example
-- modes for your simple case.
import Text.Parsec
import Text.Parsec.Char
import Text.Parsec.String
-- A data structure for your simple arithmetic expresssion
data Expr = Lit Int
| Plus Expr Expr
| Minus Expr Expr
deriving Show
-- Evaluate an Expr to an integer number
eval :: Expr -> Int
eval (Lit n) = n
eval (Plus e1 e2) = eval e1 + eval e2
eval (Minus e1 e2) = eval e1 - eval e2
-- The following do the parsing work
-- Parser for an integer number
int :: Parser Expr
int = Lit . read <$> (many1 digit <* spaces) -- A number may be followed by spaces
-- Parser for operators "Plus" and "Minus"
plus, minus :: Parser (Expr -> Expr -> Expr)
plus = Plus <$ char '+' <* spaces
minus = Minus <$ char '-' <* spaces
-- Parser for Expr
expr :: Parser Expr
expr = chainl int (plus <|> minus) (Lit 0)
-- Evalute string to an integer
evalExpr :: String -> Int
evalExpr s = case parse expr "" s of
Left err -> error $ show err
Right e -> eval e
以上只是使用parsec
的简单示例。如果您的实际情况比较复杂,则需要做更多的工作。因此,学习使用parsec
是必要的。 intro_to_parsing是一个好的开始。 package description中也有一些学习资源。
顺便说一下,Text.Parsec.Expr
中的parsec
可以更方便地解析表达式,但是最重要的是,您需要了解parsec
的基本知识。
学习愉快!
答案 1 :(得分:0)
与您的示例相距不远。试试这个:
evalExpr :: String -> Int
evalExpr xs = foldl f (0 +) xs 0
f :: (Int -> Int) -> Char -> (Int -> Int)
f v ch | ch == '+' = (v 0 +)
| ch == '-' = (v 0 -)
| ch == ' ' = v
| otherwise = (v (read [ch] :: Int) +)
所以与您的主要区别在于,折数中的累加器是一个可以吸收一个Int并产生一个Int的函数,而不仅仅是一个Int。