Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/haskell/10.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Haskell 是否应该为main指定类型签名?为什么?_Haskell_Main_Conventions_Compiler Flags_Type Signature - Fatal编程技术网

Haskell 是否应该为main指定类型签名?为什么?

Haskell 是否应该为main指定类型签名?为什么?,haskell,main,conventions,compiler-flags,type-signature,Haskell,Main,Conventions,Compiler Flags,Type Signature,我从中吸取了教训 按照惯例,我们通常不为main指定类型声明 据我所知,这种习俗很普遍。但是,如果我使用-Wall标志编译一个缺少main类型签名的程序,例如 --test.hs --main::IO() main=print(1::Int) GHC确实发出警告: $ ghc -Wall test.hs [1 of 1] Compiling Main ( test.hs, test.o ) test.hs:2:1: Warning: Top-level bin

我从中吸取了教训

按照惯例,我们通常不为
main
指定类型声明

据我所知,这种习俗很普遍。但是,如果我使用
-Wall
标志编译一个缺少
main
类型签名的程序,例如

--test.hs
--main::IO()
main=print(1::Int)
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 ...
$

我很困惑。。。如果
main
的类型签名确实是多余的,为什么
-Wall
在缺少时会导致GHC投诉?指定
main
的类型是否有充分的理由(除了去掉该警告之外)?

一般来说,正如该警告所表明的,给顶级绑定一个类型签名总是一个好主意。事实上,这样说更为合理

按照惯例,我们确实为所有内容1指定了一个类型声明

当然,在一个大项目中,
main
本身是一项不可忽视的工作,因此省略签名确实没有任何意义。为了前后一致,把它写下来

然而,尽管Haskell非常适合于结构合理的项目,而且实际上有在库中编写几乎所有内容的趋势,但它作为一种快速脚本语言也出人意料地好,因为其他人会用Python或Perl编写。在这些情况下,您通常不太关心安全性和良好的文档等,您只想快速地写下尽可能简洁的内容来完成这项工作。您通常也不会使用
-Wall
编译这些脚本,而只是使用
runhaskell
执行它们。由于脚本总是需要包含
main
(与大多数其他Haskell源文件不同),因此在这里省略签名确实是明智的

我仍然怀疑,现在大多数Haskeller确实是用最简单的脚本编写
main::IO()
,如果只是出于习惯的话



1也就是说,只有顶层的所有内容。本地签名有时也有意义,但通常它们会使代码变得混乱。

实际上为
main
编写类型签名是一个非常好的主意,因为否则,如果您太喜欢尝试以无点形式编写内容,您最终可能会得到
main
类型的
IO(IO())
。这是可以接受的(语言标准说,
main
只需要有某种形式的
ioa
),但是由
main
产生的“内部IO动作”将被丢弃,这几乎肯定不是你想要的(你可能想
加入它).

感谢您的澄清。对于更大的项目,启用
-fwarn缺失签名和
-Werror
,这将强制
main
具有类型签名也是有意义的。@PetrPudlák我通常使用
-Wall
(我相信这将启用
-fwarn缺失签名)与
-Werror
一起使用。缺少顶级类型签名应为错误。事实上,它应该是非法的。非法的应该作为犯罪受到惩罚。在该语言中不是非法的。特别是,顶级导出类型签名可能是错误的。我使用了很多非常通用的助手,它们没有导出,没有公共文档,并且签名比身体长。把这些写出来没有任何帮助,只是一件烦人的事。这本书只是说,它们不会为
main
提供类型注释,以减少演示文稿中的混乱。他们并不是在暗示你不应该对它进行注释。@chi有趣;我不是那样读的。不过,我不确定这句话应该怎么解释。另一个模棱两可的“我们”的例子。很有趣。您是否可以添加一个链接,指向在标准中您阅读到的
main
只需要某种形式的
ioa
?@Jubobs:请参阅第二段,我认为不需要
main::IO()
是标准的一个(非常)小的缺陷。然而,这是个人喜好的问题。当
main
IO(IO a)
结尾时,您是否可以添加这样一个示例?@PetrPudlák是一个精心设计的示例:
main=return getLine
,类型为
IO(IO String)