2011-10-28 21 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」的一個很好的部分。如果你閱讀了這篇文章,但仍然覺得有點不知所措,那就這樣說吧,我會試着補充我的兩分錢。 –