2016-02-29 60 views
2

我覺得第一Shake使用演示模式,似乎很容易出錯的example爲什麼Shake依賴關係是明確「需要」的?

contents <- readFileLines $ out -<.> "txt" 
    need contents 
    cmd "tar -cf" [out] contents 

爲什麼我們需要need contentsreadFileLines讀取它們和cmd引用他們呢?這是否可以避免要求ApplicativeDo

+0

我試着詳細闡述一個答案,但我不確定我真的知道問題的核心。你認爲潛在的錯誤是什麼?您如何看待'ApplicativeDo'可能會有所幫助? –

+0

@尼爾,感謝你的開放態度:)所以這裏是我的看法。對於Haskell中沒有經驗的人來說,任何看起來「不必要」的代碼都會引發像「爲什麼你會推薦這樣寫」這樣的問題?這是否解決了懶惰IO問題?這是你如何調整並行任務到「Monad」接口(與'ApplicativeDo'的Haxl'相比)?爲什麼不用輸入文件的正確語義來定義'tar'目標呢?儘管我可能對「Shake」下的複雜Haskell內容過於謹慎。 – sevo

+0

所以你問爲什麼'需要'是必要的?這是必要的,因爲你必須告訴Shake'tar'將使用什麼,因爲它不知道'tar'的作用。你說得對,人們可以定義'tar inp out =需要inp; cmd「tar -cf」[out] inp' - 事實上,在一個更大的構建系統中,我會鼓勵這樣做。 –

回答

2

我認爲部分混亂可能是contents的類型/語義。文件out -<.> "txt"包含一個文件名列表,所以contents是一個文件名列表。當我們need contents我們要求文件本身被創建和依賴,使用文件名來指定哪些文件。當我們將contents傳遞給cmd時,我們傳遞tar將用於查詢文件的文件名。

所以關鍵是readFileLines不讀取有問題的文件,它只讀取另一個文件中的文件名。我們必須使用need來確保使用這些文件很好,然後我們實際上使用cmd中的文件。查看三條線的另一種方法是:

  1. 我們想要對哪些文件進行操作?
  2. 確保這些文件已準備就緒。
  3. 使用這些文件。

這有道理嗎?與ApplicativeDo沒有任何關係 - 它的存在根本無助於我們。

相關問題