【问题标题】:What is the motivation behind the "let definition is a constant" hint?“让定义是一个常数”提示背后的动机是什么?
【发布时间】:2018-02-21 00:20:48
【问题描述】:

启用-hints 选项后,编译器会针对以下程序发出提示消息:

module Main where

main :: IO ()
main = do
    let magic :: Int  -- (A)
        magic = 123
    println magic

.

$ fregec -hints Main.fr
H Main.fr:5: let definition is a constant: magic
calling: javac -cp /home/yohashi/lib/java/fregec.jar:. -d . -sourcepath . -encoding UTF-8 ./Main.java 

这个提示试图“暗示”反对什么?


如果我省略了 (A) 行上的类型注释(抱歉,术语不正确),提示就会消失:

main = do
    let magic = 123
    ...

类型归属也不会带来提示:

main = do
    let magic = 123 :: Int

where 声明也会发生同样的事情:

main = println magic
  where
  magic :: Int
  magic = 123                     -- let definition is a constant: magic
  magica = 123                    -- no hint
  magicb = 123 :: Int             -- no hint
  magicfun :: Int -> Int
  magicfun = succ                 -- let definition is a constant: magicfun
  magicfuna = succ                -- no hint
  magicfunb = succ :: Int -> Int  -- no hint
  magicfunc :: Int -> Int
  magicfunc i = succ i            -- no hint

magicfun 上的提示特别烦人,因为它不鼓励使用无点表示法(与 magicfunc 相比)。

所以我的问题是:这个提示背后的动机是什么? 我认为为简单或复杂的表达式提供别名是let/where 的有效用途。提示是否另有暗示?

【问题讨论】:

    标签: frege


    【解决方案1】:

    你说得对,缩写一个常量或给一个函数起别名是完全可以的。但是,提示不是警告,而只是有关您的程序的信息,可能会或可能不会告诉您一些您还不知道的事情。

    因此,“暗示反对”的概念是错误的。你也不应该努力让你的代码“无提示”。

    具有讽刺意味的是,有问题的提示似乎需要另一个提示来解释它。它应该是:

    我,编译器,用于将类型注释常量(如您的“name”)移动到顶层,因为这样做是安全的,并且可能会消除一些或所有嵌套层级。这也将加速以后的类型检查、代码生成和运行时间。此外,您可能会考虑自己做同样的事情,以免最终在不同的 let 表达式或 where 子句中一遍又一遍地定义相同的常量。

    请注意,在

    foo :: Int
    foo = 42
    

    我们在注释foo,而在

    foo = 42 :: Int
    

    我们只对右侧进行注释,因此从技术上讲,foo 没有注释,必须进行类型推断。这就是看似不合理和令人困惑的差异的来源。

    【讨论】:

    • 感谢您的回答。我曾将提示视为“扩展警告”,您的解释清楚地表明了意图。但是,我想保留-hints 以进行某些检查,例如未使用的进口。所以我不同意“你也不应该努力让你的代码'提示免费'”;养成忽略诊断信息的习惯是一件坏事。也许添加命令行选项来禁用/启用每个提示,如 -Wno-let-constant 可能会有所帮助。
    • 一个更好的提示信息的候选者是:“constant let 定义将被移到顶层。”
    • 我认为我们将删除该提示,因为它确实令人困惑。关于未使用的导入,它们并没有那么大的伤害,只是在编译时你需要有相应的类文件。
    猜你喜欢
    • 2021-05-20
    • 2018-11-19
    • 2017-09-20
    • 2012-04-04
    • 2019-08-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-10-04
    相关资源
    最近更新 更多