为什么以下在列表推导中尝试进行模式匹配的方法行不通?
示例:在术语数据类型中同时替换原子。
数据类型:
这是期望的行为,而且
示例:在术语数据类型中同时替换原子。
数据类型:
data Term a
= Atom a
| Compound (Term a) (Term a)
deriving Show
在项中进行原子替换的算法(如果有多个匹配项,则选择第一个匹配项并忽略其余的):
subs :: [(Term a, Term a)] -> Term a -> Term a
subs subList term = case term of
atom@(Atom x) -> let substitutions =
[ s | s@(Atom x, _) <- subList ]
in if null substitutions
then atom
else snd . head $ substitutions
(Compound t1 t2) -> Compound (subs subList t1) (subs subList t2)
一些测试数据:
subList = [((Atom 'a'), Compound (Atom 'b') (Atom 'c'))]
term1 = Atom 'a'
term2 = Atom 'x'
运行示例的结果如下:
>: subs subList term1
Compound (Atom 'b') (Atom 'c')
这是期望的行为,而且
>: subs subList term2
Compound (Atom 'b') (Atom 'c')
但是这并不是。
奇怪的是,显式匹配有效:
subs'' :: [(Term Char, Term Char)] -> Term Char -> Term Char
subs'' subList term = case term of
atom@(Atom _) -> let substitutions =
[ s | s@(Atom 'a', _) <- subList ]
in if null substitutions
then atom
else snd . head $ substitutions
(Compound t1 t2) -> Compound (subs subList t1) (subs subList t2)
subs''' subList term = case term of
atom@(Atom _) -> let substitutions =
[ s | s@(Atom 'x', _) <- subList ]
in if null substitutions
then atom
else snd . head $ substitutions
(Compound t1 t2) -> Compound (subs subList t1) (subs subList t2)
使用测试数据进行反馈,结果如下:
>: subs'' subList term1
或者 >: subs'' subList term2
复合型(原子'b')(原子'c')
>: subs''' subList term1
或者 >: subs''' subList term2
原子'x'
我错过了什么吗?
-Wall
打开GHC警告:这将指出x
被绑定两次(内部的x
掩盖了外部的x
)。 - chi