Haskell中的变量

sen*_*nel 5 variables haskell

为什么以下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的第一个示例创建两个新的局部变量vk已填充了元组的内容t.模式匹配不会比较t现有变量的内容k,而是创建一个新变量k(隐藏外部变量).

通常,模式中不会发生任何"变量替换",模式中的任何变量名称始终会创建新的局部变量.