我对哈斯克尔有点陌生。我读过一本或两本教程,但经验不多。
Haskell中的每个函数都是纯的,这就是为什么没有IO-monad就不能有任何I/O。我不明白的是,为什么程序参数也必须是IO操作?参数像传递给函数一样传递给程序。为什么不能像在函数中那样访问参数?
为了弄清楚,我不明白,为什么主要功能必须这样
main :: IO()
main = do
args <- getArgs
print args而不是这个
main :: [String] -> IO()
main args = do
print args我看不出有什么理由,也没找到答案。
发布于 2021-02-26 22:56:29
这是语言设计的选择。这两种方法都没有比另一种方法更好。
Haskell可以设计成两种类型的main。
当您确实需要程序参数时,将它们作为函数参数传递给main会更方便。
当不需要程序参数时,将它们传递给main有点麻烦,因为我们需要编写一个更长的类型,并需要一个额外的_来丢弃[String]参数。
此外,getArgs允许一个人访问程序中任何地方(在IO中)的程序参数,而只将它们传递给main,这样就不太方便了,因为这样一个人就会被迫在程序中传递它们,这可能会很不方便。
(简短的离题)很久以前,当我发现在Java中我们有void main()而不是C中的int main()时,我和你的反应是相似的。然后我意识到,在大多数程序中,我总是在最后编写return 0;,所以总是要求这样做没有什么意义。在Java中,这是隐式默认值,当我们真正需要返回其他内容时,我们使用System.exit()。即使这是在前一种语言(在本例中是C)中实现的方式,新的语言也可以选择一种新的方式来提供相同的功能。
发布于 2021-02-27 00:11:14
我倾向于同意chi的回答,即没有明显的令人信服的理由必须这样做,所以这真的可以归结为一小群人很久以前所作的主观判断。不能保证它背后会有任何特别令人满意的理由。
以下是我脑海中浮现的一些推理(这可能是最初的设计师们在当时想过的,甚至可能是不同意的)。
我们真正爱的是所能做的事情:
main :: Integer -> String -> Set Flag -> IO ()(对于某些假设的程序,它以整数、字符串和一组标志作为命令行参数)
能够编写小的命令行程序,就好像它们只是命令行参数的一个函数一样,那就太棒了!但是这需要操作系统(或者至少是shell)来理解Haskell程序中使用的类型,并且知道如何解析它们(如果解析失败,或者没有足够的参数,等等),这是不会发生的。
也许我们可以编写一个包装器来完成这个任务。它可以负责将原始字符串命令行参数解析为Haskell类型并生成错误消息(如果需要),然后为我们调用main。但是等等,我们完全可以做到!我们只需调用包装器main (并重命名我们以前所称的main)!
要点是:如果你想把你的程序看作是一个简单的外部输入函数,那就很有意义了,但是main 不是函数。main作为一个包装器工作得更好,它处理通过非类型化接口接收输入和调用“真正是”您的程序的函数的丑陋细节。
强迫您在设置代码中包含对getArgs的调用,这使得处理命令行参数比仅仅访问它们更明显,并可能促使您编写一些额外的处理代码,而不仅仅是编写main (arg1 : arg2 : _) = do stuffWith arg1 arg2。
此外,将我们必须的接口转换为您想要的接口也是超级琐碎的事情:
import System.Environment
main = real_main =<< getArgs
real_main :: [String] -> IO ()
real_main args = print args所以你可以用任何你喜欢的方式!
https://stackoverflow.com/questions/66393690
复制相似问题