***例外:Prelude.read:Haskell中不解析 - 解析,表达式和递归
这部分代码应该读取两个或更多数字(省略主io函数),然后用“+”来给出总和。理性被使用,因为后来我会做乘法和其他操作。***例外:Prelude.read:Haskell中不解析 - 解析,表达式和递归
data Expression = Number Rational
| Add (Expression)(Expression)
deriving(Show,Eq)
solve :: Expression -> Expression
solve (Add (Number x) (Number y)) = Number (x + y)
parse :: [String] -> [Expression] -> Double
parse ("+":s)(a:b:xs) = parse s (solve (Add a b):xs)
parse [] (answer:xs) = fromRational (toRational (read (show answer)::Float))
parse (x:xs) (y) = parse (xs) ((Number (toRational (read x::Float))):y)
(第二)错误是用解析功能无法处理
*Main> parse ["1","2","+"] [Number 3]
*** Exception: Prelude.read: no parse
我已经看过了Data.Ratio页面和网页此解决方案上,但还没有找到它,会感谢一些帮助。谢谢,
CSJC
第一个方程,
parse ("+":s)(a:b:xs) = parse (s)((solve (Add (Number a) (Number b))):xs)
应该
parse ("+":s)(a:b:xs) = parse (s)((solve (Add a b)):xs)
,因为每个类型签名,a
和b
已经是Expression
秒。
或者,在与第二和第三方程线,所述类型更改为
parse :: [String] -> [Rational] -> Double
和第一方程改变为固定代码的
parse ("+":s)(a:b:xs) = parse s ((a + b):xs)
两种可能的方法(有是更有问题的部分):
-- Complete solve to handle all cases
solve :: Expression -> Expression
solve [email protected](Number _) = expr
solve (Add (Number x) (Number y)) = Number (x + y)
solve (Add x y) = solve (Add (solve x) (solve y))
-- Convert an Expression to Double
toDouble :: Expression -> Double
toDouble (Number x) = fromRational x
toDouble e = toDouble (solve e)
-- parse using a stack of `Expression`s
parse :: [String] -> [Expression] -> Double
parse ("+":s) (a:b:xs) = parse s ((solve (Add a b)):xs)
parse [] (answer:_) = toDouble answer
parse (x:xs) ys = parse xs (Number (toRational (read x :: Double)) : ys)
parse _ _ = 0
-- parse using a stack of `Rational`s
parseR :: [String] -> [Rational] -> Double
parseR ("+":s) (a:b:xs) = parseR s (a+b : xs)
parseR [] (answer:xs) = fromRational answer
parseR (x:xs) y = parseR xs ((toRational (read x::Double)):y)
parseR _ _ = 0
后者比较谨慎,因为最终生成了Double
,所以使用Rational
作为堆栈没有真正的意义。
在您的parse
代码,第三个方程省去了通过Number
构造一个Rational
到Expression
的转换,但在其他方面正常。第二个公式,但是,含有不同类型的问题:
parse [] (answer:xs) = fromRational (toRational (read (show answer)::Float))
如果answer
或者是一个Expression
或Rational
,show answer
不能被解析为一个Float
,这样将导致一个运行时间错误,通过所例示您编辑:
(第二)错误是用解析功能无法处理
*Main> parse ["1","2","+"] [Number 3]
*** Exception: Prelude.read: no parse
在其中使用所述第二方程点,堆叠在所述第一元件(answer
)是Number (3 % 1)
,和show (Number (3 % 1))
是"Number (3 % 1)"
,其不是String
该read
可以作为一个Float
解析。
太好了,谢谢你澄清这一点。 – CSJC 2012-04-26 17:50:34
这是否也适用于'solve(Add(Number x)(Number y))= Number(x + y)'可以是'solve(Add x y)= Number(x + y)'? – CSJC 2012-04-26 18:00:24
编号在'Add x y'中,'x'和'y'是'Expression's,但Number'需要一个'Rational'参数,'(+)'没有为'Expression'定义。就解决方案而言,“解决”是正确的(当然,它是不完整的)。 – 2012-04-26 18:05:06
你的第二个错误是在我的答案已经处理:) – 2012-04-26 18:43:15
是的,看来你已经抢占这样的事情,因为我打字吧! – CSJC 2012-04-26 18:48:21