我正在尝试编写一个程序,它在命令行上接受两个整数并用它们做一些有趣的事情。我想尽可能容易和命令地编写整数的读取/解析,因为它应该是相对简单的代码。
我面临的问题是在 Haskell 中处理错误并不是那么简单。似乎在 Haskell 中经常使用模式匹配。这似乎使代码比命令式版本更难遵循。
该程序将像这样运行(在此示例中,它只是将两个数字相加):
$ ./my_prog
ERROR: Must run like `./my_prog NUM_A NUM_B`.
$ ./my_prog cat 1
ERROR: Could not parse NUM_A "cat" as integer
$ ./my_prog 10 dog
ERROR: Could not parse NUM_B "dog" as integer
$ ./my_prog 10 1
11
这是我想在命令式伪 Python 中做的事情:
function die (errorMessage):
print("ERROR: %s" % errorMessage)
sys.exit(1)
function main ():
if len(sys.argv) != 2:
die("Must run program like `%s NUM_A NUM_B`" % sys.progname)
num_a = 0
num_b = 0
try:
num_a = int(sys.argv[0])
except:
die("Could not parse NUM_A \"%s\" as integer" % sys.argv[0])
try:
num_b = int(sys.argv[1])
except:
die("Could not parse NUM_B \"%s\" as integer" % sys.argv[1])
doSomethingInteresting(num_a, num_b)
function doSomethingInteresting (num_a, num_b):
print(num_a + num_b)
在 python 中,您基本上可以从上到下读取 main 函数,并且所有错误处理都很简单。 有没有办法在 Haskell 中实现这种简单、直接的错误处理,而无需进行多个模式匹配?
这是我提出的执行相同任务的 Haskell 代码,但由于多个模式匹配部分,它似乎比 Python 代码复杂得多。
module Main ( main
)
where
import System.Environment (getArgs, getProgName)
import System.Exit (ExitCode(..), exitWith)
import Text.Read (readMaybe)
die :: String -> IO a
die err = do putStrLn $ "ERROR: " ++ err
exitWith (ExitFailure 1)
main :: IO ()
main = do
args <- getArgs
progName <- getProgName
case args of
[strNumA, strNumB] -> do
let maybeNumA = readMaybe strNumA :: Maybe Int
maybeNumB = readMaybe strNumB :: Maybe Int
checkMaybeArgs strNumA maybeNumA strNumB maybeNumB
_ -> die ("Must run like `" ++ progName ++ " NUM_A NUM_B`.")
where
checkMaybeArgs :: String -> Maybe Int -> String -> Maybe Int -> IO ()
checkMaybeArgs badStrNumA Nothing _ _ =
die ("Could not parse NUM_A \"" ++ badStrNumA ++ "\" as integer")
checkMaybeArgs _ _ badStrNumB Nothing =
die ("Could not parse NUM_B \"" ++ badStrNumB ++ "\" as integer")
checkMaybeArgs _ (Just numA) _ (Just numB) = doSomethingInteresting numA numB
doSomethingInteresting :: Int -> Int -> IO ()
doSomethingInteresting numA numB = print $ numA + numB
(此外,如果我的 Haskell 风格有任何其他问题,我将非常感谢任何更正。)
编辑:我最近发现一篇博客文章讨论了在 Haskell 中处理异常的许多不同方法。这有点相关:
http://www.randomhacks.net/articles/2007/03/10/haskell-8-ways-to-report-errors