簡體   English   中英

為什么列表推導在Haskell中沒有錯誤地接受混合的`[Char]`和`[[Char]]`?

[英]Why does a list comprehension accept mixed `[Char]` and `[[Char]]` without error in Haskell?

在學習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'] [y | y <- 'a']無效,因為'a'不是列表。

[/編輯]

我認為這是由String vs Char引起的一些常見的混亂,但絕對不是:

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

為了記錄我正在使用GHCi版本8.2.2和Arch Linux。

打開警告! 您應該看到第一個y被第二個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]] [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]

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM