Не существует общего, простого способа сопоставления с шаблонами с общими переменными:
foo (Bar a b) = ...
foo (Baz a b) = ...
и последующей записью выражений (в предложениях where
или в других местах), таких что a
и b
соответствуют обе модели одновременно. В Haskell шаблон создает новую область видимости, в которой переменные в шаблоне связаны этим шаблоном, и нет никакого способа «объединить» эти привязки - использование a
или b
будет либо ссылаются на привязки в Bar a b
или Baz a b
, но не одновременно.
Самое лучшее, что вы можете сделать, это использовать оператор case
для применения общего where
предложение для нескольких шаблонов и использование общей вспомогательной функции, которая принимает a
и b
в качестве аргументов и явно связывает их с общими именами на основе шаблона:
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)