haskell: classic program calculator.hs + nested constructor patterns (+5 tests, 402/402)
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
40
lib/haskell/tests/programs/calculator.hs
Normal file
40
lib/haskell/tests/programs/calculator.hs
Normal file
@@ -0,0 +1,40 @@
|
||||
-- calculator.hs — recursive descent expression evaluator.
|
||||
--
|
||||
-- Tokens are represented as an ADT; the parser threads a [Token] list
|
||||
-- through a custom Result type so pattern matching can destructure the
|
||||
-- pair (value, remaining-tokens) directly inside constructor patterns.
|
||||
--
|
||||
-- Operator precedence: * and / bind tighter than + and -.
|
||||
-- All operators are left-associative.
|
||||
|
||||
data Token = TNum Int | TOp String
|
||||
data Result = R Int [Token]
|
||||
|
||||
getV (R v _) = v
|
||||
getR (R _ r) = r
|
||||
|
||||
eval ts = getV (parseExpr ts)
|
||||
|
||||
parseExpr ts = parseExprRest (parseTerm ts)
|
||||
|
||||
parseExprRest (R v (TOp "+":rest)) =
|
||||
let t = parseTerm rest
|
||||
in parseExprRest (R (v + getV t) (getR t))
|
||||
parseExprRest (R v (TOp "-":rest)) =
|
||||
let t = parseTerm rest
|
||||
in parseExprRest (R (v - getV t) (getR t))
|
||||
parseExprRest r = r
|
||||
|
||||
parseTerm ts = parseTermRest (parseFactor ts)
|
||||
|
||||
parseTermRest (R v (TOp "*":rest)) =
|
||||
let t = parseFactor rest
|
||||
in parseTermRest (R (v * getV t) (getR t))
|
||||
parseTermRest (R v (TOp "/":rest)) =
|
||||
let t = parseFactor rest
|
||||
in parseTermRest (R (v `div` getV t) (getR t))
|
||||
parseTermRest r = r
|
||||
|
||||
parseFactor (TNum n:rest) = R n rest
|
||||
|
||||
result = eval [TNum 2, TOp "+", TNum 3, TOp "*", TNum 4]
|
||||
Reference in New Issue
Block a user