是否应该为main指定类型签名?为什么/为什么不呢?

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 只有顶层的所有东西,即.本地签名有时也有意义,但通常它们会使代码混乱.


Rei*_*ton 8

写一个类型签名实际上是一个非常好的主意main,因为如果你太过花哨试图以无点形式编写东西,你最终会main得到类型IO (IO ()).这是被接受的(语言标准说main只需要有某种形式IO a),但结果的"内部IO动作" main将被丢弃,这几乎肯定不是你想要的(你可能想要join它) .

  • 我认为不要求`main :: IO()`是标准的(非常)次要缺陷.然而,这是个人品味的问题. (4认同)