OCaml绘制直线函数drawLine的if...then begin...end语法错误修复求助
Fixing Syntax Issues in Your OCaml Bresenham's Line Implementation
Let's break down the syntax problems in your drawLine function and fix them step by step. OCaml's statement block and semicolon rules are a bit different from imperative languages like C, so it's easy to trip up here.
Key Syntax Problems in Your Code
- Incorrect reference comparison: You're comparing the reference values (
xx = x1) instead of the integer values stored in the references (!xx = x1). Sincexxis anint ref, comparing it directly to an integerx1will always be false, which breaks your loop termination condition. - Missing semicolons between sequential expressions: In OCaml, semicolons are used to separate expressions that need to run in sequence (not to end statements). For example, when you update
ERRand thenxxin the samebegin...endblock, you need a semicolon between those two assignments. - Unnecessary ref variables: You're creating ref variables (
xx,yy,ERR) inside the inner function when you don't actually need them—you can work with the parameters directly using mutable state or adjust the logic to avoid refs entirely (though we'll keep refs here to stay close to your original approach).
Fixed Code Implementation
let drawLine image colour start finish = match (image, start, finish) with | (Image ((w,h), pixels), (x0, y0), (x1, y1)) -> let dx = abs(x1 - x0) in let dy = abs(y1 - y0) in let sx = if x0 < x1 then 1 else -1 in (* More readable than Bool.to_int *) let sy = if y0 < y1 then 1 else -1 in let err = dx - dy in let rec inner x y myErr = (* First, set the current pixel *) pixels.(y).(x) <- colour; (* Check if we've reached the end point *) if not (x = x1 && y = y1) then let new_err = ref myErr in let new_x = ref x in let new_y = ref y in begin if !new_err * 2 > -dy then begin new_err := !new_err - dy; new_x := !new_x + sx end; if !new_err * 2 < dx then begin new_err := !new_err + dx; new_y := !new_y + sy end; inner !new_x !new_y !new_err end in inner x0 y0 err
What Changed?
- Fixed termination condition: Replaced the incorrect reference comparison with a check against the actual integer values of
xandy, avoiding the loop never ending. - Added missing semicolons: Added semicolons between sequential assignments in the
begin...endblocks to ensure OCaml interprets them as ordered operations. - Improved readability: Replaced
Bool.to_int (x0 < x1)with an explicitif...then...elseforsxandsy—this makes the code easier to understand without changing functionality. - Cleaned up ref usage: Moved ref declarations inside the
ifblock (since we only need them if we haven't reached the end point) and removed unnecessarybegin...endwrapping around the entire inner function body.
Additional Notes
OCaml is a functional-first language, so you could also rewrite this to avoid mutable refs entirely by passing updated values directly in the recursive call. This is more idiomatic OCaml and avoids mutable state:
let rec inner x y err = pixels.(y).(x) <- colour; if x = x1 && y = y1 then () else let (new_err, new_x) = if err * 2 > -dy then (err - dy, x + sx) else (err, x) in let (final_err, final_y) = if new_err * 2 < dx then (new_err + dx, y + sy) else (new_err, y) in inner final_x final_y final_err
内容的提问来源于stack exchange,提问作者TDizzleFoShizzle
相关产品推荐
相关产品推荐

