2017-10-05 46 views
3

假設我們有一個文件my_file.txt與內容:海龜:如何閱讀文件列表?

foo 
bar 

,幷包含另一個文件my_other_file.txt

baz 

我想用turtle讀這兩個文件的內容,讓我得到一個Shell將生產的線路:

foo 
bar 
baz 

在Haskell的turtle庫可以通過使用input讀取文件的列表,例如:

view $ input "my_file.txt" 

我們有

input :: FilePath -> Shell Line 

而且Shell沒有Monoid情況下(我認爲是有道理的,因爲我們不能關聯IO操作),所以我能想到的唯一的運營商是(<|>)

view $ foldl (<|>) empty $ map input ["my_file.txt", "my_other_file.txt"] 

雖然這會產生所需的效果,但我想知道是否在生態系統中有一個庫處理此問題,或者是否存在可在Alternative上使用的類似操作traverse

EDIT:上述的效果可以通過使用asum也實現:

asum $ input <$> ["my_file.txt", "my_other_file.txt"] 

回答

3

Line具有Monoid實例。如果我們有Line秒的列表,我們可以mconcat成一個單一的一個:

do 
    exampleA <- input "my_file.txt" 
    exampleB <- input "my_other_file.txt" 
    return $ mconcat [exampleA, exampleB] 

由於ShellApplicative情況下,我們可以使用traverse使用input在文件的列表:

traverse input ["my_file.txt","my_other_file.txt"] 

我們以Shell [Line]結束。由於ShellFunctor,我們可以fmapmconcat(或fold,如果你不使用列表):

mconcat <$> traverse input ["my_file.txt","my_other_file.txt"] 
+0

我已經試過了,但它似乎並不工作。 'view $ traverse input [「my_file.txt」,「my_other_file.txt」]'yield'[Line foo',Line「baz」] [Line bar「,line」baz「]',所以整體結果當應用'mconcat'時將是'Line「foobaz」 Line「barbaz」'。或者我錯過了什麼? –