我最近打開了GHC的-Wall
選項,其中包括-fwarn-name-shadowing
。所提供的基本原理是:與fwarn-name-shadowing的可讀性權衡
該選項使要發射的警告每當內範圍值具有相同的名稱作爲外範圍的值,即內值陰影外一個。這可以避免印刷錯誤,變成難以發現的錯誤。
但在實踐中我還沒有抓到任何錯誤,但是我有在我的職能方面取得的變量命名了很多尷尬的解決它。縮寫示例:
-- General method for parsing a paragraph.
paragraph :: Parser Node
paragraph = undefined -- omitted for brevity
blockquote :: Parser Node
blockquote = lookAhead (char '>')
>> Blockquote
<$> paragraph' `sepBy1` blankLine
where
-- Avoid shadowing a `paragraph` method defined above.
-- This one is more specialized and relevant only in
-- this context.
paragraph' = Paragraph <$> body
這似乎有點臭我,但我有其他的案件變得更糟 - 比如我有一個功能,我最終避免使用remainder'
和sections'
陰影remainder
和sections
,並然後在一個嵌套的where
條款我直接去r
和s
,以避免進一步陰影 - 我想知道-fwarn-name-shadowing
是否在平衡淨積極。我認爲我可以做一些重構來避免一些陰影而不會招致這些尷尬的名字的間接,但這並不總是可能的。
我最好是允許一些陰影,還是我應該重新考慮這樣的例子來讓氣味消失?我懷疑後者,但我不確定。
有時也會讓我感到厭煩。我真正想要的是某種方式讓編譯器神奇地警告我*意外地*影子名稱,但不是當我故意重複使用名稱時。沒有魔法的唯一方法就是如果我標記故意的陰影案例;我也許應該標記陰影名稱的*使用*,以確保我不會死腦筋,並試圖從同一範圍內引用具有相同名稱的兩個不同事物。但是很難想象一種標記允許陰影的方式,而不是僅僅停留在「事物上」,而是用更少的語法開銷! – Ben
我始終堅持通過重命名綁定來消除警告,但我認爲這是個人偏好的問題。我喜歡在代碼中間看到一個標識符,並且知道如果它具有頂級綁定,那就是真的。此外,在定義輔助函數時,很容易重用一些參數名稱,比如'xs',然後混淆兩個綁定。有時候,也可以寫一個意外的遞歸綁定。不過,我可以看到有時候這個警告有點煩人。 – chi
@ben,我認爲你以'_'開頭的任何內容都不會發出警告,所以這也是一個選項。這樣,如果你想重複使用和嵌套'foo'兩次,你可以做'_foo','_foo','_foo'而不是'foo','foo'','foo''。 – wincent