Read file as List[String] with ZIO

Hey! I don’t see many ZIO related questions here, I hope the topic is still welcome. If not, I’ll be happily pointed somewhere else.

So I’m toying around with this year’s advent of code and ZIO, and I’d like to have the inputs as .txt files. That means I’ll have to read those contents from disk into my program, and I decided to go with List[String] because after all, text is always string, and parsing can be done more specifically later on.

To this point, I’ve come this far:

  // return type annotation is just for clarification, I'm not settled with having this exact type
  private def parseFile(fileName: String): ZIO[Any, Throwable, Seq[String]] =
    val path = "src/main/resources/" + fileName
    val lines: zio.stream.Stream[Throwable, String] =
      zio.stream.Stream.fromIteratorManaged(
        ZManaged.fromAutoCloseable(
          Task(Source.fromFile(path))
        ).map(_.getLines())
      )
    lines
      .runCollect

  val program =
    for
      fileContent <- parseFile("0101.txt")
      _ <- putStrLn(s"$fileContent")
    yield ()

  def run(args: List[String]) = // main function
    program.exitCode

The input file I’m working on (link will only work if you are logged in yourself) looks something like this:

143
147
...
187
...

This somewhat works, but the output looks like Chunk(143,147,...,187...), which means:
a) it’s a singular String instead of List[String] despite calling getLines() and the annotated types
b) surrounded by Chunk(...) which breaks further parsing down the line

I believe lines.runCollect might not do what I think it does, as well as reading the file via a Stream was the wrong approach in the first place. My search for how to read files functionally using ZIO has always yielded examples done in a similar fashion though.

Answering my own question: Chunk is a collection in its own right (I didn’t know until someone pointed me to that circumstance and it wasn’t obvious from the part of the implementation I read). Therefore, the code in fact worked kind of fine already.
Because Chunks are all kind of lazy, I now convert them to List so I can work with them more easily, but maybe you wouldn’t have to do that if you’re fine with working with them. After all, my code looks like this now:

  def parseFile(fileName: String): ZIO[Any, Throwable, Seq[String]] =
    val path = "src/main/resources/" + fileName
    val lines: zio.stream.Stream[Throwable, String] =
      zio.stream.Stream.fromIteratorManaged(
        ZManaged
          .fromAutoCloseable(
            Task(Source.fromFile(path))
          )
          .map(_.getLines())
      )
    lines
      .runCollect
      // apart from formatting, this is actually new (evaluates all Chunks):
      .map(_.toList) 

That is the best outcome anyone ever hopes for. Apologies to the proof community, if in fact they form a community.

I don’t see a zio hashtag on the forum for AoC. I still mix up AoC and AOC. A recent crossword answer was AC/DC which suggests a pun advent of code/debugging of code.