• Post Reply Bookmark Topic Watch Topic
  • New Topic
programming forums Java Mobile Certification Databases Caching Books Engineering Micro Controllers OS Languages Paradigms IDEs Build Tools Frameworks Application Servers Open Source This Site Careers Other Pie Elite all forums
this forum made possible by our volunteer staff, including ...
Marshals:
  • Campbell Ritchie
  • Jeanne Boyarsky
  • Ron McLeod
  • Paul Clapham
  • Liutauras Vilda
Sheriffs:
  • paul wheaton
  • Rob Spoor
  • Devaka Cooray
Saloon Keepers:
  • Stephan van Hulst
  • Tim Holloway
  • Carey Brown
  • Frits Walraven
  • Tim Moores
Bartenders:
  • Mikalai Zaikin

Idiomatically extracting Success from a sequence of Try?

 
Bartender
Posts: 2407
36
Scala Python Oracle Postgres Database Linux
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
I'm writing some code to parse a CSV file where I simply want to throw away any records that don't have the right format. I'm using Scala Try() to wrap the extraction process for each line of input data, which produces a sequence of Try's. Then I filter these and do a get() on the Successes to create a list of my required class instances. But I'm wondering if there's a more idiomatic way of extracting the results from the sequence of Try's.

Here is a simplified version of my code, which reads Strings from an imaginary CSV file, and wants to convert them to a Fubar which has 3 Int fields. I know it's not the done thing, but in this case I'm not interested in trapping any parsing exceptions - I just want the valid data.

Now I can run this code with some dummy data:
Results from Step 1 are fine:
Now run the second step:
The end results are exactly what I want i.e. a sequence of valid instances of Fubar:
So my code does what I want and it's pretty concise, but I still think there is vague code-smell around the Try/Success processing. Anybody got any better ideas?
 
Ranch Hand
Posts: 121
12
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Hi, Chris

I suggest using Seq.flatMap + Try.toOption:



If your are not interested in errors at all, I suggest using your own method returning an option and ignoring errors:
 
chris webster
Bartender
Posts: 2407
36
Scala Python Oracle Postgres Database Linux
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Thanks, Maxim. I like the idea of turning the Try into an Option and using flatMap, as it's easier to handle consistently but still makes it easy enough to respond to errors if necessary. I'd feel a bit less comfortable simply swallowing the exception, as in your second example, even though I'm not interested in errors currently.

Thanks for the helpful suggestions - it's good to get input from other people as this stuff is still pretty new to me!
 
Greenhorn
Posts: 2
Scala Java Ubuntu
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
We actually had a similar dilemma and after some time settled on using ScalaZ disjunctions. They are composable, don't swallow exceptions (unless you ask them to), can be converted to Option's etc. I even wrote a blog post about it a couple of months ago:

http://appliedscala.com/blog/2016/scalaz-disjunctions/

Some people are turned off by an operator-like syntax, but they can use Xor from Cats, which is basically a clone of ScalaZ disjunction.
 
Ranch Hand
Posts: 239
12
Scala IntelliJ IDE Eclipse IDE Java Ubuntu
  • Likes 1
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Hi Chris,

My idea from reading Programming in Scala recently (new edition just came out) is that the idiomatic way of doing it is with the "collect" function which is the equivalent of filter + map in one function.

You could just change getSuccessful to something like this and preserve the rest as is:



But I think completely idiomatic usage would be to use a deep pattern match and do it all in one collect statement:

 
reply
    Bookmark Topic Watch Topic
  • New Topic