Haskell `where` 模式匹配
Haskell `where` with pattern-matching
我有这样的功能:
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
我想用一种 where
用法重写它。我可以做吗?但是模式匹配应该留在这段代码中。谢谢!
没有通用、直接的方法来匹配具有公共变量的模式:
foo (Bar a b) = ...
foo (Baz a b) = ...
然后编写表达式(在 where
子句或其他地方)使得 a
和 b
同时对应于两种模式。在 Haskell 中,一个模式创建了一个新的作用域,其中模式中的变量被该模式绑定,并且没有办法 "combine" 这些绑定——a
或 [= 的用法14=] 将 引用 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)
我有这样的功能:
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
我想用一种 where
用法重写它。我可以做吗?但是模式匹配应该留在这段代码中。谢谢!
没有通用、直接的方法来匹配具有公共变量的模式:
foo (Bar a b) = ...
foo (Baz a b) = ...
然后编写表达式(在 where
子句或其他地方)使得 a
和 b
同时对应于两种模式。在 Haskell 中,一个模式创建了一个新的作用域,其中模式中的变量被该模式绑定,并且没有办法 "combine" 这些绑定——a
或 [= 的用法14=] 将 引用 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)