使用此代码:
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
?
答案 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
。