2012-06-12 74 views
1

这有点长,所以请耐心等待!Haskell Noob需要帮助

我在使用Haskell程序时遇到了一些麻烦,我必须使用它作为uni项目的一部分。作为参考,它是Casper

所以,你应该执行一个脚本,它实际上是一个bash脚本调用拥抱的解释是这样的:

exec $HUGSBIN/hugs $HUGSARGS +p"Casper> " $FILES 

其中$ FILES指向Main.lhs文件。

之后,我需要在解释器中调用一个带有文件路径的“compile”函数。

我需要以脚本方式执行上述操作。我需要这种自动化,因为我正在编写一个程序,在后台调用Casper。

所以我编译了.lhs文件。现在我想执行“编译”功能,但我不知道这是如何完成的。我尝试:

./Main compile <a path> 

从命令行但它返回一个关于文件“测试”未找到错误。经过调查,我在Main.lhs文件中看到这些行:

>main :: String -> IO() 
>main = compile "test" 

>compile :: String -> IO() 
>compile s = catch (compile0 False s) handler 

[...snipped] 

第二行解决了这个问题。现在我的问题是,如何在编译main.lhs之后调用“compile”函数并传递路径给它?从解释器中,我只需键入“compile”并且它可以工作,但是在编译main.lhs并从命令行执行后,我无法获得相同的工作。任何想法为什么?如果一切都失败了,有什么办法可以编写拥抱?

谢谢你的帮助!

+0

用 – applicative

+0

代替'main'把主体替换成? –

回答

4

您可以通过getArgs访问传递给Haskell程序的命令行参数。例如,它听起来像你想要一个这样的主要功能:

>main = do 
> args <- getArgs 
> case args of 
>  [] -> putStrLn "What file did you want me to compile?" 
>  [filename] -> compile filename 
>  _ -> putStrLn "I only compile one file at a time." 

修改成品味。

+0

工作正常!非常感谢!你能解释你的代码做什么吗?除了对Haskell不熟悉之外,我有点了解它。我特别想知道最后3行的含义。我假设:空字符串,打印消息。如果提供了arg,则将其称为“文件名”并调用“编译文件名”。如果多于一个参数,告诉最后一条消息? –

+0

@ Inf.S:这基本上是正确的。'getArgs'是一个给出命令行参数列表的动作。第一行将此列表绑定到名称“args”。列表可以具有可变数量的元素,因此最后一行在列表上进行模式匹配以找出如何继续。如果'args'与空列表匹配,则显示消息。如果args与单个元素匹配列表,则调用该元素'filename'并继续编译该文件。最后一行使用'_'来匹配。这是一种特殊情况的匹配,总是成功的,但是模式匹配的规则是从上到下匹配(续) – Boris

+0

@ Inf.S :(续)如果匹配成立,它意味着前两行不匹配,所以它必须是两个或更多元素的列表。如果最后一行是'case args of'后面的第一行,那么程序只会打印'“我一次只编译一个文件”,不管它有多少个参数。 – Boris

2

替换main

main = getArgs >>= \(arg1:_) -> compile arg1 

这将第一命令行参数(arg1)传递给compile而不是 “检验”,而忽略其余的(_)。您可能需要添加

import System 

import System.Environment 

我不记得什么需要拥抱这一点。

+0

我得到这个:Main.lhs:31:9:不在范围内:'getArgs'。想法?] –

+0

这是“>导入System.Environment”。我使用了Daniel Wagner的代码,因为它对我来说更加清晰。但你的作品也是!谢谢! –