2011-10-28 34 views
2

我正在努力理解一个在命令式世界中极其简单的代码块。 这就是我需要做的:给定一个可执行完整路径,这是一个Maybe FilePath类型,我需要有条件地执行它。 如果路径是一个Nothing - 打印一个错误,如果路径是Just Path - 执行它并打印文件已执行的消息。只有“你好,世界”可以更容易,对吗?但是在Haskell中,我将自己挖掘到Maybe和IO的许多层,并陷入困境。 从这里出现两个具体问题: 如何将Maybe FilePath提供给系统或rawSystem? liftM在这里不适合我。 做这种条件分支的正确方法是什么? 谢谢。Haskell:有条件地使用Maybe FilePath执行外部进程

+1

简单的'case'和模式匹配有什么问题? – delnan

+1

你有没有尝试'可能FilePath'上的模式匹配? –

回答

11

简单的模式匹配将很好地完成这项工作。

case command of 
    Just path -> system path >> putStrLn "Done" 
    Nothing -> putStrLn "None specified" 
+0

当你知道它是如此容易。我现在知道了,“>>”做到了。 –

+0

尽管我知道“>>”的作用,但我似乎无法在需要时使用它。感谢排序的例子。但它没有显示如何将Maybe值输入到系统函数中。我没有原始的命令字符串,我只有一个Just路径或Nothing。下面,我可以看到Traversable解决方案。还有别的事吗? –

+0

@ r.sendecky:恩,可以用'do {system path; puStrLn“完成”; ''为'Just'情况。至于“提供可能的价值到系统功能” - 你不能。 'system'只需要一个'String',而不是'Maybe String'。无论如何,在调用'system'之前,你必须解开它(获取包含的字符串)。你必须以某种方式处理“Nothing”,例如你不能试图解开它(将是一个'错误')。 “可穿越”解决方案只是一个捷径。 – delnan

3

或者,如果你不想模式匹配,使用maybe功能:

maybe (putStrLn "None specified") ((>> putStrLn "Done") . system) command 

这有时可能比用case匹配更好,但不是在这里,我想。成功信息印刷的构成是笨重的。如果你不显示消息,但在两个分支返回ExitCode它好:

maybe (return $ ExitFailure 1) system command 
+0

非常好,很短。学习非常有用。虽然这个命令不包含在Maybe中。上面的Traversable示例是否是唯一的方法? –

+0

Hammar和我(后面的hammar)都给包装的命令命名了“命令”,所以命令是“Just realCommand”或“Nothing”(或底部)。如果你想让IO操作返回一个'Maybe ExitCode'或者类似的东西,你可以使用:'maybe(return Nothing)(fmap Just。system)maybeCommand',但是如果你多次使用它,导入Data .Traversable和使用遍历是较少打字。 –

3

这正是Traversable类型的类被造的!

Prelude Data.Traversable System.Cmd> traverse system Nothing 
Nothing 
Prelude Data.Traversable System.Cmd> traverse system (Just "echo OMG BEES") 
OMG BEES 
Just ExitSuccess 
+0

我会质疑你的第一句话,但是,遍历对此也是非常好的。+1 –

+0

是的,这很好。我至今还不能理解它,但它是有效的。即使在阅读不幸的可读性后,它也没有点击。当你看到你的东西工作,但你不明白为什么,这是非常烦人的。非常感谢这个例子。如果你有一分钟​​,我将不胜感激对可遍历的简单解释。 –

+1

@ r.sendecky如果你还没有看过[Typeclassopedia](http://www.haskell.org/wikiupload/e/e9/Typeclassopedia.pdf),我强烈推荐它。它从Typeclassopedia(相应Monad阅读器版本的第47页)开始,介绍了“Traversable”的一个很好的部分。如果你阅读了这篇文章,但仍然觉得有点不知所措,那就这样说吧,我会试着补充我的两分钱。 –