jub*_*0bs 14 haskell program-entry-point conventions compiler-flags type-signature
我从"学习你是一个伟大的好的哈斯克尔"的第9章中学到了这一点
按照惯例,我们通常不会为其指定类型声明
main.
据我所知,这个惯例很普遍.但是,如果我使用-Wall标志编译一个缺少类型签名的程序main,例如
-- test.hs
-- main :: IO ()
main = print (1 :: Int)
Run Code Online (Sandbox Code Playgroud)
GHC确实发出警告:
$ ghc -Wall test.hs
[1 of 1] Compiling Main ( test.hs, test.o )
test.hs:2:1: Warning:
Top-level binding with no type signature: main :: IO ()
Linking test ...
$
Run Code Online (Sandbox Code Playgroud)
我很困惑......如果类型签名main确实是多余的,为什么-WallGHC会在它丢失时抱怨?是否有充分的理由(除了摆脱那个警告)指定main的类型?
lef*_*out 14
好吧,一般来说,正如警告所表明的那样,为顶级绑定提供类型签名总是一个好主意.事实上,说更合理
按照惯例,我们为所有事物1指定一个类型声明.
当然,在一个大项目中,main本身构成了一种可忽略的努力,所以省略签名真的没有任何意义.为了保持一致性,请写出来.
然而,尽管Haskell对于结构合理的项目非常有用,并且实际上有一种倾向于在库中编写几乎所有内容,但它作为一种快速脚本语言也是出乎意料的好,对于其他人用Python或Perl编写的东西.在这些情况下,您通常不太关心安全性和良好的文档等,您只是想快速写下尽可能简洁的工作.您通常也不会编译这些脚本,-Wall而只是执行它们runhaskell.并且由于脚本总是需要包含一个main(与大多数其他Haskell源文件不同),因此在这里省略签名确实足够明智.
我还是怀疑,大多数Haskellers时下不写main::IO(),即使在最简单的脚本,如果只是出于习惯.
1 只有顶层的所有东西,即.本地签名有时也有意义,但通常它们会使代码混乱.
写一个类型签名实际上是一个非常好的主意main,因为如果你太过花哨试图以无点形式编写东西,你最终会main得到类型IO (IO ()).这是被接受的(语言标准说main只需要有某种形式IO a),但结果的"内部IO动作" main将被丢弃,这几乎肯定不是你想要的(你可能想要join它) .