为什么列表推导在Haskell中没有错误地接受混合的`[Char]`和`[[Char]]`?

时间:2018-03-08 11:51:08

标签: haskell types polymorphism list-comprehension parametric-polymorphism

在学习Haskell的过程中,我发现了令我困惑的事情。

我不明白为什么这段代码有效:

Prelude> [y | y <- "a", y <- ["a"]]
["a"]

我尝试更改为显式[Char]并获得相同的结果(这是有道理的):

Prelude> [y | y <- ['a'], y <- ["a"]]
["a"]

令人惊讶的是,这也是有效的:

Prelude> [y | y <- "a", y <- [["a"]]]
[["a"]]

[编辑] 给出的错误与同一事实无关:

相反,我的预期无效:

Prelude> [y | y <- 'a', y <- ['a']]
<interactive>:12:11: error:
* Couldn't match expected type `[t0]' with actual type `Char'
* In the expression: 'a'
  In a stmt of a list comprehension: y <- 'a'
  In the expression: [y | y <- 'a', y <- ['a']]

<击>

[y | y <- 'a']无效,因为'a'不是列表。

[/编辑]

我认为这是由String vs Char引起的常见混乱,但绝对不是:

Prelude> [y | y <- [1], y <- [[2]]]
[[2]]

我记录的是使用GHCi版本8.2.2和Arch Linux。

1 个答案:

答案 0 :(得分:11)

开启警告!你应该看到第一个y被第二个let y = True in let y = "a" in y 遮蔽了。

它与

类似
let _ = True
in let y = "a"
in y

第一个定义黯然失色,好像它是

let y = "a"
in y

甚至删除阴影绑定

[y | y <- "a", y <- ["a"]]

同样,列表理解如

[y | _ <- "a", y <- ["a"]]
-- or, if you prefer
[y | x <- "a", y <- ["a"]]

评估与

相同的结果
let

请注意,与上面的y <- ...不同,在列表推导中,我们不能简单地删除黯然失色的绑定[y | y <- [1,2], y <- [3,4]] 。例如,

[3,4,3,4]
[y | y <- [3,4]]不同,

生成Prelude> :set -Wall Prelude> [y | y <- "a", y <- ["a"]] <interactive>:41:6: warning: [-Wunused-matches] Defined but not used: `y' <interactive>:41:16: warning: [-Wname-shadowing] This binding for `y' shadows the existing binding bound at <interactive>:41:6 ["a"] Prelude> [y | x <- "a", y <- ["a"]] <interactive>:47:6: warning: [-Wunused-matches] Defined but not used: `x' ["a"] -- no warning here Prelude> [y | _ <- "a", y <- ["a"]] ["a"] Prelude> [y | y <- [1,2] , y <- [3,4]] <interactive>:49:1: warning: [-Wtype-defaults] * Defaulting the following constraints to type `Integer' (Show a0) arising from a use of `print' at <interactive>:49:1-29 (Num a0) arising from a use of `it' at <interactive>:49:1-29 * In a stmt of an interactive GHCi command: print it <interactive>:49:6: warning: [-Wunused-matches] Defined but not used: `y' <interactive>:49:12: warning: [-Wtype-defaults] * Defaulting the following constraint to type `Integer' Num t0 arising from the literal `1' * In the expression: 1 In the expression: [1, 2] In a stmt of a list comprehension: y <- [1, 2] <interactive>:49:12: warning: [-Wtype-defaults] * Defaulting the following constraint to type `Integer' Num t0 arising from the literal `1' * In the expression: 1 In the expression: [1, 2] In a stmt of a list comprehension: y <- [1, 2] <interactive>:49:19: warning: [-Wname-shadowing] This binding for `y' shadows the existing binding bound at <interactive>:49:6 [3,4,3,4]

在这里,您可以看到每个示例的生成警告:

<activity android:name="com.facebook.CustomTabMainActivity" />