Given:
def convert[T](list: List[Either[String, T]]): Validated[NonEmptyList[String], NonEmptyList[T]] =
NonEmptyList.fromList(list)
.toRight("list is empty")
.flatMap(...
How do I flat map the NonEmptyList[Either[String, T]] so ultimately I end up with my Validated return value?
Is there anything in the cats library to account for this scenario? Or do I need to do this manually following something like: Best way to turn a Lists of Eithers into an Either of Lists?
I'd write this as follows:
import cats.data.{ NonEmptyList, Validated, ValidatedNel }
import cats.instances.list._, cats.syntax.list._
import cats.syntax.either._
import cats.syntax.option._
import cats.syntax.traverse._
def convert[T](list: List[Either[String, T]]): ValidatedNel[String, NonEmptyList[T]] =
list.traverse(_.toValidatedNel).andThen(_.toNel.toValidNel("list is empty"))
First we flip the whole thing inside out while transforming the Eithers to Validateds (with traverse and toValidatedNel), to get a ValidatedNel[String, List[T]], and then we handle the case where the result is empty (with andThen and toNel).
The andThen is probably one of the pieces you're missing—it's essentially flatMap for Validated (but without the implications and syntactic sugar baggage that flatMap brings). If you wanted you could probably pretty easily change my version to do the empty list check first, as in your sketch, but the way I've written it feels a little more natural to me.
Footnote: I have no idea why the enrichment method for Option is named toValidNel while the one for Either is toValidatedNel—I hadn't noticed this before, probably because I hadn't used them in the same line before. This seems unfortunate, especially since we're stuck with it for a while now that Cats 1.0 is out.
Another footnote: note that you'll need the -Ypartial-unification compiler option enabled for traverse to work without type parameters if you're on 2.11.
Related
I am new to scala. Currently I am trying to develop a calculator as scala project.
But while trying to find the sum I am getting problem. The following code doesn't compile.
def add [T](values :List[T]) : Option[T]={
if (values.isInstanceOf[String]) {
None
}
else if(values.isInstanceOf[Int] || values.isInstanceOf[Long] || values.isInstanceOf[Double]) {
Some(values.sum)
}
}
When you're new to a language, it is important to start slow and discover the abstractions rather than impose them right away without the experience to make it work. I also think it is a bad idea to just rely on standard library functions (unless you are in a hurry) like sum or to look at third-party libraries until you fully understand what the standard library offers.
So in other words, first let's look at ways to solve the problem just for Int:
def add(values: List[Int]) = values.reduce((a, b) => a + b)
The reduce function works because the type of the result matches the type of what is in the list. The contents are Ints, and the sum is an Int. You will also find this can be simplified with some syntactic sugar:
def add(values: List[Int]) = values.reduce(_ + _)
Wait until you see all the ways underscores get used in Scala.
As you keep studying, you will find that in order to accumulate a value that is a different type than what's in the list, you can use one of the fold* methods. But they can work here too, so for example you could also do this:
def add(values: List[Int]) = values.foldLeft(0)(_ + _)
Now try to define the same function for Long, Double, or even String. You will find the implementations will be almost identical.
It's only when you see implementations that look really similar if not identical that you should even think about abstractions. One option to solve this problem is with type classes. They aren't easy for beginners though. Daniel Westheide wrote a great post on the topic, and frankly you would do well to read the whole series as you learn Scala.
I've really simplified things and glossed over a lot of topics (like why foldLeft has two parameter lists with the first one being 0 or what those crazy implicit things are in Daniel's type classes post), but my advice is to be patient and move slowly. Scala isn't easy, but you'll get it.
(But if you are in a hurry and you are a beginner, I think you are better off just using sum and then writing separate functions for each type. This would be an example of what agile author Kenny Rubin would call "necessary" or "unavoidable" technical debt, and that's to be expected from beginners. Just refactor later.)
Or more generic (example with amm):
# import $ivy.`org.typelevel:cats_2.12:0.8.1`
import $ivy.$
# import cats._, cats.implicits._
import cats._, cats.implicits._
# List(1, 2, 3).combineAll
res2: Int = 6
# List("1", "2", "3").combineAll
res3: String = "123"
# List(List(1, 2), List(), List(3)).combineAll
res5: List[Int] = List(1, 2, 3)
Or via fiddle. It works by using the Monoid and Traversable typeclass.
I'm using the Reader monad in Scala as provided by the scalaz library. I'm familiar with this monad as defined in Haskell. The problem is that I cannot find the functions equivalent to return, local, and sequence (among others).
Currently I use constructs that I do not like since I'm repeating myself or making my code a bit obscure.
Regarding return, I'm currently using:
Reader{_ => someValue}
I'd rather just use a construct like unit(someValue), but I could not find anything on the internet. There are tutorials like this one that use the approach above, and which I consider not optimal.
Regarding local I also have to do something similar: instead of typing something like: local f myReader I have to unfold its definition:
Reader{env => myReader.run(f(env))
Finally, sequence is a bit closer to what I would expect (being a Haskell refugee doing Scala):
readers: List[Reader[Env, T]]
readerTs: Reader[Env, List[T]] = readers.sequenceU
My problem with this implementation is that, being relatively new to Scala, the type of sequenceU
final class TraverseOps[F[_],A] private[syntax](val self: F[A])(implicit val F: Traverse[F]) extends Ops[F[A]] {
//...
def sequenceU(implicit G: Unapply[Applicative, A]): G.M[F[G.A]]
appears like rather obscure, and seems like black magic. Ideally I would like to use a sequence operations on Monads.
Is there a better translation of these constructs to Scala available on scalaz or similar library? I'm not married to any Functional library for Scala, so any solution using other libraries will do, although I'd rather have an answer using scalaz, since I already implemented my code using it.
To make the things simpler, I fill in some types. Changing them to defs with generic types should still work.
Also I extracted the ReaderInt type, to avoid confusion with type lambdas.
return / pure / point
Scala does not have automatic typeclass resolution, so you need to provide them implicitly. For Kleisli (being a monad transformer for reader),
Kleisli[Id, ?, ?] is enough
implicit val KA = scalaz.Kleisli.kleisliIdApplicative[Int]
type ReaderInt[A] = Kleisli[Id.Id, Int, A]
val alwaysHello = KA.point("hello")
or with imported syntax:
import scalaz.syntax.applicative._
val alwaysHello = "hello".point[ReaderInt]
So as a general rule, you
1) import the applicative intance, which usually located in scalaz.std.something.somethingInstance
2) import scalaz.syntax.something._
3) then you can write x.point[F], where F is your applicative.
local
Not sure, that it answers your question, but Kleisli has a local method.
val f: String ⇒ Int = _.length
val alwaysEleven = alwaysHello local f
sequencing
The same way, you are free to choose to use syntax for or to specify type classes explicitly.
import scalaz.std.list.listInstance
val initial: List[ReaderInt[String]] = ???
val sequenced: ReaderInt[List[String]] = Traverse[List].sequence[ReaderInt, String](initial)
import scalaz.syntax.traverse._
val z = x.sequence[ReaderInt, String]
I prefer not to use sequenceU, which uses Unapply typelcass to infer the G type, because sometimes scala has troubles of figuring out the right one.
And I personally do not find it messy to put in some types myself.
It may worth to look into cats, though it does not have much yet.
What is the cleanest way in Scala to convert from Future[Option[Future[Int]]] to Future[Option[Int]]? Is it even possible?
There are two nested Futures that you roll into one, so this calls for a flatMap.
def flatten[A](f: Future[Option[Future[A]]]): Future[Option[A]] =
f.flatMap({
case None => Future.successful(None)
case Some(g) => g.map(Some(_))
})
Or, more concisely:
def flatten[A](f: Future[Option[Future[A]]]): Future[Option[A]] =
f.flatMap(o => Future.sequence(o.toSeq).map(_.headOption))
Thanks to #lmm's answer for the idea on that. Ideally this could be written as f.flatMap(Future.sequence), but unfortunately sequence expects a TraversableOnce, which Option does not extend.
The cleanest way is probably using scalaz:
import scalaz.std.option._
import scalaz.std.scalaFuture._
import scalaz.syntax.traverse._
//assuming implicit execution context in scope
f.flatMap(_.sequence)
You are asking how to code your way out of some paper bag, and you have gotten some good answers about how to do this, however you should be stepping back and trying to just not get into the paper bag you are currently in. See my answer here: Get rid of Scala Future nesting about how to avoid getting into a Future[X[Future[y]] type signature so that you don't have to figure out how to then get out of it.
The following Scala code works correctly:
val str1 = "hallo"
val str2 = "huhu"
val zipped: IndexedSeq[(Char, Char)] = str1.zip(str2)
However if I import the implicit method
implicit def stringToNode(str: String): xml.Node = new xml.Text(str)
then the Scala (2.10) compiler shows an error: value zip is not a member of String
It seems that the presence of stringToNode somehow blocks the implicit conversion of str1 and str2 to WrappedString. Why? And is there a way to modify stringToNode such that zip works but stringToNode is still used when I call a function that requires a Node argument with a String?
You have ambiguous implicits here. Both StringOps and xml.Node have the zip-method, therefore the implicit conversion is ambiguous and cannot be resolved. I don't know why it doesn't give a better error message.
Here are some links to back it up:
http://www.scala-lang.org/api/current/index.html#scala.collection.immutable.StringOps
and
http://www.scala-lang.org/api/current/index.html#scala.xml.Node
edit: it was StringOps, not WrappedString, changed the links :) Have a look at Predef: http://www.scala-lang.org/api/current/index.html#scala.Predef$
to see predefined implicits in Scala.
I would avoid using implicits in this case. You want 2 different implicit conversions which both provide a method of the same name (zip). I don't think this is possible. Also, if you import xml.Text, you can convert with just Text(str) which should be concise enough for anyone. If you must have this implicit conversion to xml.Node, I would pack the implicit def into an object and then import it only in the places where you need it to make your code readable and to, possibly, avoid conflicts where you also need to zip strings. But basically, I would very much avoid using implicits just to make convenient conversions.
Like #Felix wrote, it is generally a bad idea to define implicit conversions between similar data types, like the one you used. Doing that weakens type system, leads to ambiguities like you encountered and may produce extremely unclear ("magic") code which is very hard to analyze and debug.
Implicit conversions in Scala are mostly used to define lightweight, short-lived wrappers in order to enrich API of wrapped type. Implicit conversion that converts String into WrappedString falls into that category.
Twitter's Effective Scala has a section about this issue.
Having written a few scala tools, I'm trying to come to grips with the best way to arrange my code - particularly implicits. I have 2 goals:
Sometimes, I want to be able to import just the implicits I ask for.
Othertimes, I want to just import everything.
To avoid duplicating the implicits, I've come up with this structure (similar to the way scalaz is arranged):
case class StringW(s : String) {
def contrived = s + "?"
}
trait StringWImplicits {
implicit def To(s : String) = StringW(s)
implicit def From(sw : StringW) = sw.s
}
object StringW extends StringWImplicits
// Elsewhere on Monkey Island
object World extends StringWImplicits with ListWImplicits with MoreImplicits
This allows me to just
import StringW._ // Selective import
or (in most cases)
import World._. // Import everything
How does everyone else do it?
I think that implicit conversions are dangerous if you don't know where they are coming from. In my case, I put my implicits in a Conversions class and import it as close to the use as possible
def someMethod(d: Date) ; Unit {
import mydate.Conversions._
val tz = TimeZone.getDefault
val timeOfDay = d.getTimeOfDay(tz) //implicit used here
...
}
I'm not sure I like "inheriting" implicits from various traits for the same reason it was considered bad Java practice to implement an interface so you could use its constants directly (static imports are preferred instead).
I usually had implicit conversions in an object which clearly signals that what it is imported is an implicit conversion.
For example, if I have a class com.foo.bar.FilthyRichString, the implicit conversions would go into com.foo.bar.implicit.FilthyRichStringImplicit. I know the names are a bit long, but that's why we have IDEs (and Scala IDE support is getting better). The way I do this is that I feel it is important that all the implicit conversions can be clearly viewed in a 10 second code review. I could look at the following code:
// other imports
import com.foo.bar.FilthyRichString
import com.foo.bar.util.Logger
import com.foo.bar.util.FileIO
import com.foo.bar.implicits.FilthyRichStringImplicit._
import com.foo.bar.implicits.MyListImplicit._
// other implicits
and at a glance see all the implicit conversions that are active in this source file. They would also be all gathered together, if you use the convention that imports are grouped by packages, with a new line between different packages.
Along the lines of the same argument, I wouldn't like a catch-all object that holds all of the implicit conversions. In a big project, would you really use all of the implicit conversions in all your source files? I think that doing that means very tight coupling between different parts of your code.
Also, a catch-all object is not very good for documentation. In the case of explicitly writing all the implicit conversions used in a file, one can just look at your import statements and straight away jump to the documentation of the implicit class. In the case of a catch-all object, one would have to look at that object (which in a big project might be huge) and then search for the implicit conversion they are after.
I agree with oxbow_lakes that having implicit conversion in traits is bad because of the temptation of inheriting from it, which is, as he said, bad practice. Along those lines, I would make the objects holding the implicit conversions final just to avoid the temptation altogether. His idea of importing them as close to the use as possible is very nice as well, if implicit conversions are just used sparingly in the code.
-- Flaviu Cipcigan