I have such function:
eval :: Expr -> Either ArithmeticError Int
eval (Const a) = Right a
eval (Add a b) = liftM2 (+) ea eb
where
ea = eval a
eb = eval b
eval (Sub a b) = liftM2 (-) ea eb
where
ea = eval a
eb = eval b
I would like to rewrite this with one where
usage. Can I do it? But pattern-matching should stay in this code. Thanks!
There's no general, straightforward way of matching against patterns with common variables:
foo (Bar a b) = ...
foo (Baz a b) = ...
and then writing expressions (in where
clauses or elsewhere) such that a
and b
correspond to both patterns simultaneously. In Haskell, a pattern creates a new scope in which variables in the pattern are bound by that pattern, and there's no way to "combine" those bindings -- a usage of a
or b
will either refer to the bindings in Bar ab
or Baz ab
, never both.
About the best you can do is use a case
statement to apply a common where
clause to multiple patterns and make use of a common helper function that takes a
and b
as arguments and explicitly rebinds them to common names, on a pattern-by-pattern basis:
eval :: Expr -> Either ArithmeticError Int
eval e = case e of
Const a -> Right a
Add a b -> go (+) a b
Sub a b -> go (-) a b
where go op a b = liftM2 op (eval a) (eval b)
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.