2017-10-05 49 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”'。或者我错过了什么? –