如果启用-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
的有效用法。提示暗示不是吗?
答案 0 :(得分:1)
你是对的,缩写函数的常量或别名是完全正常的。但是,提示不是警告,而只是关于你的程序的评论,可能会或可能不会告诉你一些你还不知道的事情。
因此,“提示反对”的概念是错误的。你也不应该努力使你的代码“免费提示”。
具有讽刺意味的是,看起来有问题的提示需要另外一些提示来解释它。它应该是:
我,编译器,用于将类型注释常量(如“ name ”)移动到顶层,因为这样做是安全的,并且可能会消除一些或所有嵌套级别的let。这也将在以后的类型检查,代码生成和运行时加快速度。另外,您可能会考虑自己做同样的事情,以免最终在不同的let表达式或where子句中反复定义相同的常量。
请注意,
foo :: Int
foo = 42
我们正在注释foo
,而在
foo = 42 :: Int
我们仅对右侧进行注释,因此从技术上讲,foo
没有注释,必须进行类型推断。所以这就是看似不合理和混乱的差异所在。