I have this:
Set[ValidatedNel[String, Double]]
and I would like to sum the Doubles in it to get:
ValidatedNel[String, Double]
If some elements in the values are then I would like to have matching strings.
I played with Set.sum and Numeric to no avail...
Here is the test of what I would like to achieve:
test("Summing ValidatedNel works") {
val val1: ValidatedNel[String, Double] = Valid(1.0)
val val2: ValidatedNel[String, Double] = Valid(2.0)
val values: Set[ValidatedNel[String, Double]] = Set(val1, val2)
val validatedNelNumeric: Numeric[ValidatedNel[String, Double]] = ???
val sum = values.sum(validatedNelNumeric)
assert(sum == Valid(3.0))
}
I don't manage to create the validatedNelNumeric...
To start with: it feels a little weird to use a set in this case (for a collection of Validated[..., Double] values). What part of the Set semantics do you care about? The unorderedness? Uniqueness?
In general the most straightforward way to sum up elements that have a Monoid instance is to use the combineAll method for things with a Foldable instance—for example a List (but not Set).
import cats.data.{ Validated, ValidatedNel }
import cats.instances.double._, cats.instances.list._
import cats.syntax.foldable._
// or just import cats.implicits._
val val1: ValidatedNel[String, Double] = Validated.valid(1.0)
val val2: ValidatedNel[String, Double] = Validated.valid(2.0)
val bad1: ValidatedNel[String, Double] = Validated.invalidNel("foo")
val bad2: ValidatedNel[String, Double] = Validated.invalidNel("bar")
val values = Set(val1, val2)
val withSomeBadOnes = Set(val1, bad1, val2, bad2)
And then:
scala> values.toList.combineAll
res0: cats.data.ValidatedNel[String,Double] = Valid(3.0)
scala> withSomeBadOnes.toList.combineAll
res1: cats.data.ValidatedNel[String,Double] = Invalid(NonEmptyList(foo, bar))
I'm guessing that's what you mean by "If some elements in the values are then I would like to have matching strings"?
You could also use SortedSet, since Cats provides a Foldable instance for SortedSet, but it's not as convenient:
scala> import cats.implicits._
import cats.implicits._
scala> import scala.collection.immutable.SortedSet
import scala.collection.immutable.SortedSet
scala> (SortedSet.empty[ValidatedNel[String, Double]] ++ values).combineAll
res2: cats.data.ValidatedNel[String,Double] = Valid(3.0)
scala> (SortedSet.empty[ValidatedNel[String, Double]] ++ withSomeBadOnes).combineAll
res3: cats.data.ValidatedNel[String,Double] = Invalid(NonEmptyList(bar, foo))
You could also use the standard fold and the |+| operator for monoids:
scala> values.fold(Validated.valid(0.0))(_ |+| _)
res4: cats.data.ValidatedNel[String,Double] = Valid(3.0)
To sum up: you can't call combineAll directly on your Set, since Cats doesn't provide a Foldable for Set. I'd suggest carefully reconsidering your use of the Set in any case, but if you decide to stick with it, you have a few options: convert to List or SortedSet like I have above, use the standard fold on Set, or finally write your own Foldable[Set] or use the one from alleycats.
Related
I want to iterate over a list[List[String]] to subset it into a list[String] and then store each list from the list of lists in a val. The val's name could be anything but it should include each list index in its name.
For example:
val x: List[ List[String]] = List(List("Nike","Apple"), List("James", "Mike"))
Desired output:
group_0 : List[String] = List(Nike, Apple)
group_1 = List[String] = List(James, Mike)
Use zipWithIndex and convert into Map[String, List[String]]. Each key will be of form group_0, group_1 etc
val map = x.zipWithIndex.map(x => s"group_${x._2}" -> x._1).toMap
Access each list using key
map("group_0")
Scala REPL
scala> x.zipWithIndex.map(x => s"group_${x._2}" -> x._1).toMap
res4: scala.collection.immutable.Map[String,List[String]] = Map(group_0 -> List(Nike, Apple), group_1 -> List(James, Mike))
scala> res4("group_0")
res6: List[String] = List(Nike, Apple)
scala> res4("group_1")
res7: List[String] = List(James, Mike)
#Manoj Kumar Dhakd idea to use toMap is better
use function zipWithIndex and zip index with your lists then use map and create a Map
val listMap=x.zipWithIndex.map(grp=>"group_"+grp._2.toString->grp._1).toMap
Display your output like below
listMap.foreach(x=>println(x._1+"="+x._2))
//output:
group_0=List(Nike, Apple)
group_1=List(James, Mike)
x.zipWithIndex.foreach{case (x,y)=>println("group_"+y+": List[String] = "+x)}
Then, in Scala REPL:
scala> val x: List[ List[String]] = List(List("Nike","Apple"), List("James", "Mike"))
x: List[List[String]] = List(List(Nike, Apple), List(James, Mike))
scala> x.zipWithIndex.foreach{case (x,y)=>println("group_"+y+": List[String] = "+x)}
group_0: List[String] = List(Nike, Apple)
group_1: List[String] = List(James, Mike)
Suppose I have a few nested functors, e.g. List[Option[Int]] and need to call the map of the most inner one.
Now I am using nested maps:
scala> val opts: List[Option[Int]] = List(Some(0), Some(1))
opts: List[Option[Int]] = List(Some(0), Some(1))
scala> opts.map(o => o.map(_ + 1))
res0: List[Option[Int]] = List(Some(1), Some(2))
What if I have 3 nesting levels, for instance ?
Is there any simple alternative to nested maps ?
Yes, this is possible with scalaz.Functor:
scala> import scalaz.Functor
import scalaz.Functor
scala> import scalaz.std.list._
import scalaz.std.list._
scala> import scalaz.std.option._
import scalaz.std.option._
scala> Functor[List].compose[Option].map(List(some(0), some(1)))(_ + 1)
res1: List[Option[Int]] = List(Some(1), Some(2))
However, this is longer than to simply call map with a nested map. If you often map nested structures, you can create helper functions:
def map2[F[_], G[_], A, B](fg: F[G[A]])(f: A => B)
(implicit F0: Functor[F], G0: Functor[G]): F[G[B]] =
F0.map(fg)(g => G0.map(g)(f))
def map3[F[_], G[_], H[_], A, B](fg: F[G[H[A]]])(f: A => B)
(implicit F0: Functor[F], G0: Functor[G], H0: Functor[H]): F[G[H[B]]] =
F0.map(fg)(g => G0.map(g)(h => H0.map(h)(f)))
...
Usage:
scala> map2(List(some(0), some(1)))(_ + 1)
res3: List[Option[Int]] = List(Some(1), Some(2))
scala> map3(List(some(some(0)), some(some(1))))(_ + 1)
res4: List[Option[Option[Int]]] = List(Some(Some(1)), Some(Some(2)))
If you have a lot of nested functors and you don't want to flatten them (i.e. they're not monads or you don't want to use them as monads) - then lenses may help. There is quicklens implementation, which supports traversable lenses : http://www.warski.org/blog/2015/03/quicklens-traversing-options-and-lists/.
Example (sorry didn't try to compile it):
modify(opts)(_.each.each).using(_ + 1)
Anyway, you have to specify nesting level, but you don't have to nest functions here. And it's enough to specify it once, like (conceptual example, didn't check):
def md2[T]: (l: List[Option[T]]) => modify(l)(_.each.each)
md2[Int](opts).using(_ + 1)
From the question I understood that you are tying to prune the list iterator e.i. remove upper levels of list in that case you can use flatten which convert list of lists into a single list.
I will be removing few layers of list using flatten
Code:-
val lists = List(
List(
List(
List("1"),List("2")
),
List(
List("3"),List("4")
) ,
List(
List("a"),List("b")
),
List(
List("c"),List("d")
)
)
)
val innerVal = lists.flatten.foreach(println)
results :-
List(List(1), List(2))
List(List(3), List(4))
List(List(a), List(b))
List(List(c), List(d))
Having
(Some(1), Some(2))
I expect to get
Some((1, 2))
and having
(Some(1), None)
I expect to get
None
I realize you're asking about Scalaz, but it's worth pointing out that the standard method is not unbearably wordy:
val x = (Some(1), Some(2))
for (a <- x._1; b <-x._2) yield (a,b)
In the general case (e.g. arbitrary-arity tuples), Shapeless is best at this sort of thing.
You can use the fact that Scalaz 7 provides a Bitraverse instance for tuples and then sequence as usual (but with bisequence instead of sequence):
scala> import scalaz._, std.option._, std.tuple._, syntax.bitraverse._
import scalaz._
import std.option._
import std.tuple._
import syntax.bitraverse._
scala> val p: (Option[Int], Option[String]) = (Some(1), Some("a"))
p: (Option[Int], Option[String]) = (Some(1),Some(a))
scala> p.bisequence[Option, Int, String]
res0: Option[(Int, String)] = Some((1,a))
Unfortunately Scalaz 7 currently needs the type annotation here.
In a comment Yo Eight states that the type annotation will remain mandatory here. I'm not sure what his or her reasoning is, but it's in fact perfectly easy to write your own wrapper that will provide any appropriately typed tuple with a bisequence method and won't require a type annotation:
import scalaz._, std.option._, std.tuple._
class BisequenceWrapper[F[_, _]: Bitraverse, G[_]: Applicative, A, B](
v: F[G[A], G[B]]
) {
def bisequence = implicitly[Bitraverse[F]].bisequence(v)
}
implicit def bisequenceWrap[F[_, _]: Bitraverse, G[_]: Applicative, A, B](
v: F[G[A], G[B]]
) = new BisequenceWrapper(v)
Now (some(1), some("a")).bisequence will compile just fine.
I can't think of a good reason Scalaz wouldn't include something like this. Whether or not you want to add it in the meantime is a matter of taste, but there's definitely no theoretical obstacle to letting the compiler do the typing here.
I think that cats version will not be redundant here.
# import cats.implicits._
import cats.implicits._
# (4.some, 2.some).bisequence
res1: Option[(Int, Int)] = Some((4, 2))
# (4.some, none).bisequence
res2: Option[Tuple2[Int, Nothing]] = None
Starting Scala 2.13, this exact behavior is provided in the standard library by Option#zip:
Some(2) zip Some('b') // Some((2, 'b'))
Some(2) zip None // None
None zip Some('b') // None
None zip None // None
Before Scala 2.13, Option#zip was returning an Iterable and it was possible to combine it with headOption:
Some(2) zip Some('b') headOption // Some((2, 'b'))
Some(2) zip None headOption // None
scala> import scalaz._
import scalaz._
scala> import Scalaz._
import Scalaz._
scala> (Tuple2.apply[Int, Int] _).lift[Option].tupled
res5: (Option[Int], Option[Int]) => Option[(Int, Int)] = <function1>
scala> res5((some(3), some(11)))
res6: Option[(Int, Int)] = Some((3,11))
scala> res5((some(3), none))
res7: Option[(Int, Int)] = None
suppose I have
type VS[A] = Validation[String, A]
val v: VS[Option[A]]
val f: A => VS[B]
I want to get a result of type VS[Option[B]] but if v is a Success(None), the result should also be a Success(None). Here's an example:
scala> val v: VS[Option[String]] = some("4.5").success
v: VS[Option[String]] = Success(Some(4.5))
scala> val f = (s : String) => (try { s.toInt.success } catch { case x => x.getMessage.fail }): VS[Int]
f: String => VS[Int] = <function1>
Then:
scala> import Validation.Monad._
import Validation.Monad._
scala> (v map2 f map (_.sequence)).join
res4: scalaz.Validation[String,Option[Int]] = Failure(For input string: "4.5")
The success case is:
scala> val v: VS[Option[String]]= some("5").success
v: VS[Option[String]] = Success(Some(5))
scala> (v map2 f map (_.sequence)).join //UGLY composition
res7: scalaz.Validation[String,Option[Int]] = Success(Some(5))
And the empty case is:
scala> val v: VS[Option[String]]= none[String].success
v: VS[Option[String]] = Success(None)
scala> (v map2 f map (_.sequence)).join
res6: scalaz.Validation[String,Option[Int]] = Success(None)
Is there a "nicer" way of doing this (possibly involving kleisli composition or monad transformers)?
The monad transformer OptionT does exactly what you want here, and its flatMapF method makes usage a clean one-liner.
I'm going to use Scalaz 7's disjunction type (\/) instead of Validation in this example, since the latter isn't a monad in Scalaz 7, but the principle is the same.
import scalaz._, std.option._, syntax.id._, syntax.monad._
type DS[+A] = String \/ A
type ODS[A] = OptionT[DS, A]
def f(s: String) = try s.toInt.right catch { case e => e.getMessage.left }
Now we can write the following:
scala> val v = OptionT(some("4.5").point[DS])
v: scalaz.OptionT[DS,java.lang.String] = OptionT(\/-(Some(4.5)))
scala> (v flatMapF f).run
res0: DS[Option[Int]] = -\/(For input string: "4.5")
Or equivalently:
scala> ("4.5".point[ODS] flatMapF f).run
res1: DS[Option[Int]] = -\/(For input string: "4.5")
Or the success case:
scala> ("4".point[ODS] flatMapF f).run
res2: DS[Option[Int]] = \/-(Some(4))
Or the empty case:
scala> (OptionT(none.point[DS]) flatMapF f).run
res3: DS[Option[Int]] = \/-(None)
As desired.
'map' preserves the number of elements, so using it on a Tuple seems sensible.
My attempts so far:
scala> (3,4).map(_*2)
error: value map is not a member of (Int, Int)
(3,4).map(_*2)
^
scala> (3,4).productIterator.map(_*2)
error: value * is not a member of Any
(3,4).productIterator.map(_*2)
^
scala> (3,4).productIterator.map(_.asInstanceOf[Int]*2)
res4: Iterator[Int] = non-empty iterator
scala> (3,4).productIterator.map(_.asInstanceOf[Int]*2).toList
res5: List[Int] = List(6, 8)
It looks quite painful... And I haven't even begun to try to convert it back to a tuple.
Am I doing it wrong? Could the library be improved?
In general, the element types of a tuple aren't the same, so map doesn't make sense. You can define a function to handle the special case, though:
scala> def map[A, B](as: (A, A))(f: A => B) =
as match { case (a1, a2) => (f(a1), f(a2)) }
map: [A,B](as: (A, A))(f: (A) => B)(B, B)
scala> val p = (1, 2)
p: (Int, Int) = (1,2)
scala> map(p){ _ * 2 }
res1: (Int, Int) = (2,4)
You could use the Pimp My Library pattern to call this as p.map(_ * 2).
UPDATE
Even when the types of the elements are not the same, Tuple2[A, B] is a Bifunctor, which can be mapped with the bimap operation.
scala> import scalaz._
import scalaz._
scala> import Scalaz._
import Scalaz._
scala> val f = (_: Int) * 2
f: (Int) => Int = <function1>
scala> val g = (_: String) * 2
g: (String) => String = <function1>
scala> f <-: (1, "1") :-> g
res12: (Int, String) = (2,11)
UPDATE 2
http://gist.github.com/454818
shapeless Supports mapping and folding over tuples via an intermediary HList representation,
Sample REPL session,
scala> import shapeless._ ; import Tuples._
import shapeless._
import Tuples._
scala> object double extends (Int -> Int) (_*2)
defined module double
scala> (3, 4).hlisted.map(double).tupled
res0: (Int, Int) = (6,8)
Where the elements of the tuple are of different types you can map with a polymorphic function with type-specific cases,
scala> object frob extends Poly1 {
| implicit def caseInt = at[Int](_*2)
| implicit def caseString = at[String]("!"+_+"!")
| implicit def caseBoolean = at[Boolean](!_)
| }
defined module frob
scala> (23, "foo", false, "bar", 13).hlisted.map(frob).tupled
res1: (Int, String, Boolean, String, Int) = (46,!foo!,true,!bar!,26)
Update
As of shapeless 2.0.0-M1 mapping over tuples is supported directly. The above examples now look like this,
scala> import shapeless._, poly._, syntax.std.tuple._
import shapeless._
import poly._
import syntax.std.tuple._
scala> object double extends (Int -> Int) (_*2)
defined module double
scala> (3, 4) map double
res0: (Int, Int) = (6,8)
scala> object frob extends Poly1 {
| implicit def caseInt = at[Int](_*2)
| implicit def caseString = at[String]("!"+_+"!")
| implicit def caseBoolean = at[Boolean](!_)
| }
defined module frob
scala> (23, "foo", false, "bar", 13) map frob
res1: (Int, String, Boolean, String, Int) = (46,!foo!,true,!bar!,26)
map function gets an A => B and returns F[B].
def map[A, B](f: A => B) : F[B]
As retronym wrote Tuple2[A, B] is a Bifunctor, so you can look for the bimap function in scalaz or cats.
bimap is a function that maps both sides of the tuple:
def bimap[A, B, C, D](fa: A => C, fb: B => D): Tuple2[C, D]
Because Tuple[A, B] holds 2 values and only one value can be mapped (by convention the right value), you can just return the same value for the left side and use the right
function to map over the right value of the tuple.
(3, 4).bimap(identity, _ * 2)