i'm trying use both irrefutable pattern , bindings function evaluate reverse polish notation expression.
here code:
resolverpn :: string -> [integer] resolverpn = foldl helper [] . words helper ~stack@(x1:x2:xs) el | el == "+" = (x2 + x1) : xs | el == "-" = (x2 - x1) : xs | el == "*" = (x2 * x1) : xs | el == "/" = (x2 `div` x1) : xs | otherwise = (read el) : stack basically irrefutable fail if give list less 2 elements should used "+-*/". if function applied "10 10" should use "otherwise" , use binding "stack" , should not try break constructos, seems doesn't work that.
if instance fold helper , use [0,0] accumulator, everithing works fine if there no need of values.
can explain why code still raise "irrefutable pattern" excepton ? or how haskell evaluate ?
here simplified code :
notworking :: [int] notworking = helper [] "10" helper ~stack@(x1:x2:xs) el = (read el) : stack working:: [int] working = helper [] "10" helper ~stack el = (read el) : stack
the thumb rule is:
- an irrefutable/lazy pattern
~pmatches everything - if variable
xinpdemanded, consider constructors in syntactic tree ofpreachablexexcept moving downwards across~: value being matched evaluated match these constructors - if match above fails, raise exception
example:
case value of ~(x,y:ys,~(z,w:ws)) -> ... - if not demand anything,
valuenot evaluated - if demand
xoryorys,valueevaluated as needed matchy:ys(and triple) - if demand
zorworws,valueevaluated as needed matchy:ys,w:ws(and triple , pair)
tests:
> case undefined of ~(x,y:ys,~(z,w:ws)) -> "hello" "hello" > case (3,undefined,(4,[1])) of ~(x,y:ys,~(z,w:ws)) -> x *** exception: prelude.undefined > case (3,[],(4,[1])) of ~(x,y:ys,~(z,w:ws)) -> x *** exception: irrefutable pattern failed pattern (x, y : ys, ~(z, w : ws)) > case (3,[0],(4,undefined)) of ~(x,y:ys,~(z,w:ws)) -> x 3 > case (3,[0],(4,[])) of ~(x,y:ys,~(z,w:ws)) -> x 3 > case (3,[],(4,[1])) of ~(x,y:ys,~(z,w:ws)) -> z *** exception: irrefutable pattern failed pattern (x, y : ys, ~(z, w : ws)) > case (3,[0],(4,[])) of ~(x,y:ys,~(z,w:ws)) -> z *** exception: irrefutable pattern failed pattern (z, w : ws) in opinion, semantic nicer if every subpattern under ~ behaved if had ~ above it. e.g. if ~(x,y:ys) equivalent ~(x,~(y:ys)). current semantics allow more flexibility, though.
the rule holds in presence of "as" patterns. instance, in
case value of a@ ~(x,y:ys,~b@(z,c@(w:ws))) -> ... demanding a not evaluate value demanding other variable cause value evaluated match triple. further, demanding of x,y,ys cause evaluation match list constructor in y:ys. instead, matching b or of z,c,w,ws cause value evaluated further, match pair (z,c@(w:ws)) list w:ws, under second ~.
--here example "as" pattern outside succeed > case (1,[],(2,[3])) of a@ ~(x,y:ys,~b@(z,c@(w:ws))) -> (1,[],(2,[3])) --this fail because triple y:ys evaluated along > case (1,[],(2,[3])) of ~a@(x,y:ys,~b@(z,c@(w:ws))) -> *** exception: irrefutable pattern failed pattern a@(x, y : ys, ~b@(z, c@(w : ws))) in code can put "as" binding outside ~ this:
helper stack@ ~(x1:x2:xs) el | el == "+" = (x2 + x1) : xs | el == "-" = (x2 - x1) : xs | el == "*" = (x2 * x1) : xs | el == "/" = (x2 `div` x1) : xs | otherwise = (read el) : stack and work fine valid rpn input.
Comments
Post a Comment