最初の方程式、
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)
であるべきです。
または、第二及び第三の方程式に沿って、
parse :: [String] -> [Rational] -> Double
にタイプを変更し、そこにコードを固定する
parse ("+":s)(a:b:xs) = parse s ((a + b):xs)
2つの方法(第一の方程式を変更しますより問題の多い部分でした):
-- 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
への転換を残し、それ以外は大丈夫です。第2の式は、しかし、問題の異なるタイプを含む:
parse [] (answer:xs) = fromRational (toRational (read (show answer)::Float))
answer
がExpression
又はRational
のいずれかである場合、show answer
はFloat
として解析することができないので、によって例示されるようなことは、ランタイムエラーにつながりますあなたの編集:
(第2)の誤差は、解析機能を
*Main> parse ["1","2","+"] [Number 3]
*** Exception: Prelude.read: no parse
を処理することができません
第2式が使用される時点で、read
がFloat
として解析できるString
されていない、スタック上の最初の要素(answer
)はNumber (3 % 1)
であり、そしてshow (Number (3 % 1))
は"Number (3 % 1)"
あります。
あなたの2番目のエラーはすでに私の答えで扱われています:) –
はい、あなたはすでに私がそれを入力していたようなものを先取りしたようです! – CSJC