【发布时间】:2012-12-19 01:14:28
【问题描述】:
我正在将 Java 应用程序移植到 Haskell。 Java 应用程序的 main 方法遵循以下模式:
public static void main(String [] args)
{
if (args.length == 0)
{
System.out.println("Invalid number of arguments.");
System.exit(1);
}
SomeDataType d = getData(arg[0]);
if (!dataOk(d))
{
System.out.println("Could not read input data.");
System.exit(1);
}
SomeDataType r = processData(d);
if (!resultOk(r))
{
System.out.println("Processing failed.");
System.exit(1);
}
...
}
所以我有不同的步骤,在每个步骤之后我可以退出并显示错误代码,或者继续执行下一个步骤。
我将其移植到 Haskell 的尝试如下:
main :: IO ()
main = do
a <- getArgs
if (null args)
then do
putStrLn "Invalid number of arguments."
exitWith (ExitFailure 1)
else do
-- The rest of the main function goes here.
使用此解决方案,我将拥有大量嵌套的if-then-else(一个用于原始 Java 代码的每个退出点)。
在 Haskell 中实现这种模式是否有更优雅/惯用的方式?一般来说,什么是 Haskell 惯用的方式来实现在 Java 等命令式语言中使用的提前退出/返回?
【问题讨论】:
-
请从learnyouahaskell.com/a-fistful-of-monads 页面阅读Walking the Line 的示例。它给出了使用 Maybe 数据类型的 Monad 示例。一旦任何表达式的结果为Nothing,那么后面所有表达式的结果都是Nothing,就像您在失败点退出一样好。
-
@ManojR - 也许在这里并不适合,因为您还想知道失败的原因。
-
经典的方法是将过程拆分为“信任”处理函数(假设参数正确)和“偏执”健全性检查函数(仅检查参数是否正确)...
-
请不要使用
length检查空列表。如果您确实需要进行简单检查,但更喜欢模式匹配,请使用null,因为它将检查与为列表元素指定名称相结合,以便您可以使用它们。 -
@C. A. 麦肯:谢谢。我通常使用
null。length从 Java 原版中溜进来,我并没有太在意它,因为我希望参数列表相当短。但是,是的,null绝对是正确的选择。
标签: java haskell control-structure