Assume we have a file my_file.txt
with contents:
foo
bar
and another file my_other_file.txt
containing:
baz
I would like to read the contents of these two files using turtle
so that I get a Shell
of lines which will produce:
foo
bar
baz
In Haskell's turtle
library one can read a list of files by using input
, for instance:
view $ input "my_file.txt"
We have that
input :: FilePath -> Shell Line
And Shell
has no Monoid
instances (which I think makes sense since we cannot associate IO
operations), so the only operator I can think of using is (<|>)
:
view $ foldl (<|>) empty $ map input ["my_file.txt", "my_other_file.txt"]
While this produces the desired effect, I wonder whether there is a library in the turtle
eco-system that takes care of this, or whether there is a traverse
like operation that can be use on Alternative
's.
EDIT: the effect above could be also achieved by using asum
:
asum $ input <$> ["my_file.txt", "my_other_file.txt"]
Line
has a Monoid
instance. If we have a list of Line
s, we can mconcat
them into a single one:
do
exampleA <- input "my_file.txt"
exampleB <- input "my_other_file.txt"
return $ mconcat [exampleA, exampleB]
Since Shell
has an Applicative
instance, we can use traverse
to use input
over a list of files:
traverse input ["my_file.txt","my_other_file.txt"]
We end up with a Shell [Line]
. Since Shell
is a Functor
, we can fmap
mconcat
(or fold
if you don't use a list):
mconcat <$> traverse input ["my_file.txt","my_other_file.txt"]