Haskell - 什么使'主'独特?

时间:2011-06-06 22:09:18

标签: haskell types io compiler-errors main

使用此代码:

main :: FilePath -> FilePath -> IO ()
main wrPath rdPath = do x <- readFile rdPath
                        writeFile wrPath x

我收到以下错误:

Couldn't match expected type 'IO t0'
            with actual type 'FilePath -> FilePath -> IO()

但是,当我将'main'的名称更改为其他名称时,文件会正确编译。

关于main有什么独特之处,为什么它的类型必须是IO t0

4 个答案:

答案 0 :(得分:22)

因为语言规范says so

  

Haskell程序是模块的集合,按照惯例,其中一个必须被称为Main并且必须导出值main。程序的值是模块main中标识符Main的值,对于某些类型IO t,它必须是t类型的计算(参见第7章)。执行程序时,执行计算main,并丢弃其结果(类型t)。

答案 1 :(得分:4)

正如GolezTrol所说,所有程序都需要知道在调用函数时哪个符号开始执行。许多脚本语言不需要(或者根本不需要)main例程,因为它们可以在顶层放置语句。对于Haskell,C和许多其他语言来说情况并非如此 - 这些语言需要一个起始位置,并且按惯例是main函数(根据Haskell规范 - 参见Cat的答案)。

注意Haskell的main不接受任何与程序参数对应的参数 - 这些参数是通过System.Environment.getArgs获得的。

答案 2 :(得分:3)

与C,Java或C#一样,main是某些上下文中的特殊标识符,用于指示程序应从何处开始。

在Haskell中,main被定义为具有类型IO a。您应该为您的函数指定一个不同的名称,或者如果您确实希望它是起点,请更改其签名并让它从getArgs

命令行读取参数

虽然你没有具体问过,main也很特别,因为它是Haskell程序中唯一可以(安全地)调用IO动作的函数。 Haskell运行时将main视为特殊。

答案 3 :(得分:1)

根据定义,main是一个不带参数的函数,它返回运行时丢弃的类型IO a的值。您的错误消息是说您的main不符合这些要求。确实如此,因为main收到两个参数。

要访问命令行参数,请使用System.Environment.getArgs