为什么以下Haskell脚本无法按预期工作?
find :: Eq a => a -> [(a,b)] -> [b]
find k t = [v | (k,v) <- t]
Run Code Online (Sandbox Code Playgroud)
给定find 'b' [('a',1),('b',2),('c',3),('b',4)]
,解释器返回[1,2,3,4]
而不是[2,4]
.u
为了实现这一点,需要引入一个名为的新变量:
find :: Eq a => a -> [(a,b)] -> [b]
find k t = [v | (u,v) <- t, k == u]
Run Code Online (Sandbox Code Playgroud)
有谁知道为什么第一个变体不会产生预期的结果?
Tra*_*own 14
来自Haskell 98报告:
像往常一样,列表推导中的绑定可以影响外部范围中的绑定; 例如:
[ x | x <- x, x <- x ] = [ z | y <- x, z <- y]
另一点:如果您使用-Wall
(或特别是-fwarn-name-shadowing
)编译,您将收到以下警告:
Warning: This binding for `k' shadows the existing binding
bound at Shadowing.hs:4:5
Run Code Online (Sandbox Code Playgroud)
使用-Wall
通常是一个好主意 - 它通常会突出显示在这种可能令人困惑的情况下发生的事情.
sth*_*sth 11
模式匹配(k,v) <- t
的第一个示例创建两个新的局部变量v
和k
已填充了元组的内容t
.模式匹配不会比较t
现有变量的内容k
,而是创建一个新变量k
(隐藏外部变量).
通常,模式中不会发生任何"变量替换",模式中的任何变量名称始终会创建新的局部变量.