1
\$\begingroup\$

Does anybody have an idea on how to make this code more idiomatic? I tried to use scalaz Traverse, but it didn't really help.

Given the types and method signatures:

  type HTTPResult = Future[Either[Throwable, String]]
  type FeedResult = Either[Throwable, Feed]

  def fetchHtml(item: FeedItem): HTTPResult

  def fetchFeed(feedUrl: String): HTTPResult

Feed and FeedItem are case classes.

I am looking for a way to simplify this function:

  def fetchAll(feedUrl: String): FeedResult = {
    val feed = fetchFeed(feedUrl).apply().right.flatMap(Feed.fromXml).right

    val scoredItems = feed.map {
      _.items.par.map { feedItem ⇒
        fetchHtml(feedItem).apply().right.map { feedHtml ⇒
          feedItem.copy(score = Feed.findScore(feedHtml))
        }
      }.foldLeft(List[FeedItem]())((acc, itemE) ⇒
        itemE match {
          case Left(t) ⇒
            logger.error("Could not download item score: ", t)
            acc
          case Right(v) ⇒ v :: acc
        })
    }

    scoredItems.right.flatMap(l ⇒ feed.map(_.copy(items = l)))
  }

I tried using for, but I am using mostly map, not flatMap and the types are different, so I can't really use for for everything and would get a weird mixture.

Any idea?

\$\endgroup\$
  • \$\begingroup\$ If you will provide working example it will be easier to understand what can be done. (e.g what does the 'apply()' function do there? Future does not have apply) \$\endgroup\$ – roterl Dec 19 '14 at 7:33
  • \$\begingroup\$ My main idea is to try use the Try monad instead of this "either". But I can not figure out types for myself. I'm not sure I understand what do you do when you write val feed = fetchFeed(feedUrl).apply().right.flatMap(Feed.fromXml).right You should have a Future somewhere there (because fetchFeed is of type HTTPResult, and this is Future). Where is Future? Did I missed it? \$\endgroup\$ – Andrey Dec 19 '14 at 9:11
  • \$\begingroup\$ I am using Either instead of Try because that is what an external library returns, instead of Try so I must somehow deal with it. That library also returns a subtype of Future with an apply method that returns an Either[Throwable, String]. @roterl do you mean a working example of the first two methods? @Andrey the future is transformed into an Either when I call the apply method. Sorry I forgot this apply method only exists in that library. \$\endgroup\$ – simao Dec 19 '14 at 10:30
  • \$\begingroup\$ If it helped with the fetchAll method I could also transform the Either into a Try inside the fetchFeed and fetchHtml methods.. \$\endgroup\$ – simao Dec 19 '14 at 10:31

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Browse other questions tagged or ask your own question.