With -hints option on, the compiler emits a hint message against the following program:
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
What does this hint try to "hint" against?
If I omit the type annotation (sorry for incorrect terminology) on the line (A), the hint goes away:
main = do
let magic = 123
...
Type ascription doesn't bring a hint, either:
main = do
let magic = 123 :: Int
The same thing happens to where declarations:
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
A hint on magicfun is particularly annoying because it discourages the point-free notation (compare to magicfunc).
So my question is: what is the motivation behind this hint?
I think giving an alias for expressions simple or complex is a valid use for let/where. Is the hint suggesting otherwise?
You are right that abbreviating a constant or aliasing a function is perfectly fine. But then, hints are not warnings, but merely comments about your program that may or may not tell you something you didn't know yet.
Hence the notion of "hint against" is mistaken. Nor should you strive to make your code "hints free".
Ironically, it looks like the hint in question would need another hint to explain it. It should read:
Please note that, in
we are annotating
foo, while inwe are annotating the right hand side only, so that technically,
foois not annotated and must undergo type inference. So that's where the seemingly unjustified and confusing difference comes from.