I need to reduce an Iterable[Either[Throwable, String]] to an Either[Throwable, Iterable[String]]. I don't know if this operation is pretty common or not, haven't found nothing on the Iterable trait. So I have written this function:
def reduce[A, B](xs: Iterable[Either[A, B]]): Either[A, Iterable[B]] =
xs.collectFirst {
case Left(x) => x
} match {
case Some(x) => Left(x)
case None => Right(xs.collect{case Right(y)=> y})
}
Can anyone help me to find a better way if this one it isn't?
This operation is often called sequencing, and is available in the standard libraries of some functional languages (such as Haskell). In Scala you can either implement your own, or use an external library like Scalaz. Suppose we have the following, for example:
val xs: List[Either[String, Int]] = List(Right(1), Right(2))
val ys: List[Either[String, Int]] = List(Right(1), Left("1st!"), Left("2nd!"))
Now we can write (using Scalaz 7):
scala> import scalaz._, Scalaz._
import scalaz._
import Scalaz._
scala> xs.sequenceU
res0: Either[String,List[Int]] = Right(List(1, 2))
scala> ys.sequenceU
res1: Either[String,List[Int]] = Left(1st!)
As desired.
As a side note, this operation just requires that the outside container be traversable and that the inside container be an applicative functor. Scalaz also provides a ValidationNEL class that's a lot like Either and also fits these requirements, but using sequence on a list of ValidationNELs collects multiple errors instead of stopping at the first:
val zs: List[ValidationNEL[String, Int]] =
List(1.successNel, "1st".failNel, "2nd".failNel)
Now we get:
scala> print(zs.sequenceU)
Failure(NonEmptyList(1st, 2nd))
You could also use sequence on a list of Options, Promises, etc.
If you don't like the explicit return and want to eliminate the pattern matching while shortening the code somewhat, here is another version:
def reduce[A, B](xs: Iterable[Either[A, B]]): Either[A, Iterable[B]] =
xs collectFirst {
case Left(x) => Left(x)
} getOrElse Right(xs.flatMap(_.right.toOption))
I always find return statements a bit awkward, but this following works:
def reduce[A, B](xs: Iterable[Either[A, B]]): Either[A, Iterable[B]] =
Right(xs.collect {
case Left(x) => return Left(x)
case Right(x) => x
})
Related
I'm reading about scalaz and noticed that we can make a list of Applicatives to be an Applicative of List.
def sequenceA[F[_]: Applicative, A](list: List[F[A]]): F[List[A]] = list match {
case Nil => (Nil: List[A]).point[F]
case x :: xs => (x |#| sequenceA(xs)) {_ :: _}
}
The question is can we do the opposite? Can we transform F[List[A]] to List[F[A]]?
This is possible if the F in question is Traversable. The code you're showing is specialized for List, but in fact it holds for all Traversable functors.
This means, that for every F that's Traversable and any G that's Applicative, we can go from F[G[A]] to G[F[A]] with sequence.
List also has an Applicative, so we can use it as our G, whereas in your example List was used as the F, the Traversable functor.
An example where what you're asking works could be Option. Here's the original direction:
val x: List[Option[Int]] = ...
val y: Option[List[Int]] = x.sequence
and the other direction:
val a: Option[List[Int]] = ...
val b: List[Option[Int]] = a.sequence
We could also write another function specializing to List:
def sequenceT[F[_]: Traverse, A](list: F[List[A]]): List[F[A]] = ...
So a very very common pattern in Scala is a for comprehension as follows:
for {
i <- monadA
j <- monadB
} yield (i, j)
Similarly for 3-tuples, ..., n-tuples. This is becoming so common in my code I'd imagine that scalaz provide some awesome operator to do this for me, e.g. monadA funnyOperator monadB funnyOperator monadC. I've looked around and can't seem to find anything. So I've defined my own implicit class for 2-tuples and 3-tuples but would prefer to use scalaz.
Bonus
In response the currently accepted answer, would love to see someone tell how to make this compile:
import scalaz.Scalaz._
// Like a 1 element list
case class MyMonad[+T](x: T) {
def map[U](f: T => U): MyMonad[U] = MyMonad(f(x))
def flatMap[U](f: T => MyMonad[U]): MyMonad[U] = f(x)
}
val myMonad: MyMonad[(Int, Int)] = (MyMonad(1) |#| MyMonad(2)).tupled
and not give:
error: value |#| is not a member of MyMonad[Int]
Bonus Solution:
You need to "provide an applicative instance" e.g.
implicit def myMonadApplicative: Bind[MyMonad] = new Bind[MyMonad] {
def bind[A, B](fa: MyMonad[A])(f: A => MyMonad[B]): MyMonad[B] = fa.flatMap(f)
def map[A, B](fa: MyMonad[A])(f: A => B): MyMonad[B] = fa.map(f)
}
Given that each Monad is an Applicative you can also use
(monadA |#| monadB).tupled
E.g.
scala> val b: List[(Int, Int)] = (List(1, 2, 3) |#| List(4, 6)).tupled
b: List[(Int, Int)] = List((1,4), (1,6), (2,4), (2,6), (3,4), (3,6))
You can use sequence; I can never remember whether you need shapeless-scalaz for this or not:
(monadA, monadB).sequence
(monadA, monadB, monadC).sequence
I've recently come across a problem. I'm trying to flatten "tail-nested" tuples in a compiler-friendly way, and I've come up with the code below:
implicit def FS[T](x: T): List[T] = List(x)
implicit def flatten[T,V](x: (T,V))(implicit ft: T=>List[T], fv: V=>List[T]) =
ft(x._1) ++ fv(x._2)
This above code works well for flattening tuples I am calling "tail-nested" like the ones below.
flatten((1,2)) -> List(1,2)
flatten((1,(2,3))) -> List(1,2,3)
flatten((1,(2,(3,4)))) -> List(1,2,3,4)
However, I seek to make my solution more robust. Consider a case where I have a list of these higher-kinded "tail-nested" tuples.
val l = List( (1,2), (1,(2,3)), (1,(2,(3,4))) )
The inferred type signature of this would be List[(Int, Any)] and this poses a problem for an operation such as map, which would fail with:
error: No implicit view available from Any => List[Int]
This error makes sense to me because of the nature of my recursive implicit chain in the flatten function. However, I was wondering: is there any way I can make my method of flattening the tuples more robust so that higher order functions such as map mesh well with it?
EDIT:
As Bask.ws pointed out, the Product trait offers potential for a nice solution. The below code illustrates this:
def flatten(p: Product): List[_] = p.productIterator.toList.flatMap {x => x match {
case pr: Product => flatten(pr)
case _ => List(x)
}}
The result type of this new flatten call is always List[Any]. My problem would be solved if there was a way to have the compiler tighten this bound a bit. In parallel to my original question, does anyone know if it is possible to accomplish this?
UPD Compile-time fail solution added
I have one solution that may suit you. Types of your first 3 examples are resolved in compile time: Int, Tuple2[Int, Int], Tuple2[Int, Tuple2[Int, Int]]. For you example with the list you have heterogeneous list with actual type List[(Int, Any)] and you have to resolve the second type in runtime or it maybe can be done by macro. So you may want to actually write implicit def flatten[T](x: (T,Any)) as your error advises you
Here is the fast solution. It gives a couple of warnings, but it works nicely:
implicit def FS[T](x: T): List[T] = List(x)
implicit def FP[T](x: Product): List[T] = {
val res = (0 until x.productArity).map(i => x.productElement(i) match {
case p: Product => FP[T](p)
case e: T => FS(e)
case _ => sys.error("incorrect element")
})
res.toList.flatten
}
implicit def flatten[T](x: (T,Any))(implicit ft: T=>List[T], fp: Product =>List[T]) =
ft(x._1) ++ (x._2 match {
case p: Product => fp(p)
case t: T => ft(t)
})
val l = List( (1,2), (1,(2,3)), (1,(2,(3,4))) )
scala> l.map(_.flatten)
res0: List[List[Int]] = List(List(1, 2), List(1, 2, 3), List(1, 2, 3, 4))
UPD
I have researched problem a little bit more, and I have found simple solution to make homogeneus list, which can fail at compile time. It is fully typed without Any and match and looks like compiler now correctly resolves nested implicits
case class InfiniteTuple[T](head: T, tail: Option[InfiniteTuple[T]] = None) {
def flatten: List[T] = head +: tail.map(_.flatten).getOrElse(Nil)
}
implicit def toInfiniteTuple[T](x: T): InfiniteTuple[T] = InfiniteTuple(x)
implicit def toInfiniteTuple2[T, V](x: (T, V))(implicit ft: V => InfiniteTuple[T]): InfiniteTuple[T] =
InfiniteTuple(x._1, Some(ft(x._2)))
def l: List[InfiniteTuple[Int]] = List( (1,2), (1,(2,3)), (1,(2,(3,4)))) //OK
def c: List[InfiniteTuple[Int]] = List( (1,2), (1,(2,3)), (1,(2,(3,"44"))))
//Compile-time error
//<console>:11: error: No implicit view available from (Int, (Int, java.lang.String)) => InfiniteTuple[Int]
Then you can implement any flatten you want. For example, one above:
scala> l.map(_.flatten)
res0: List[List[Int]] = List(List(1, 2), List(1, 2, 3), List(1, 2, 3, 4))
I have a monad that is very similar to a collection monad. I'm currently trying to implement a monad transformer for it, but I'm failing.
I've looked at the ListT implementation in Scalaz 6 and 7, but I cannot understand how it works. It uses some additional type Step, whose purpose is unclear to me.
So can someone please explain to me how to implement a list monad transformer, either by explaining the Scalaz approach or using a different implementation?
I am not quite sure, what the Step means in scalaz, but implementing a ListT is pretty straight forward. Depending on how many operations you want to put on it, it can be a little work, but the basic monad operations can be implemented as follows.
First we need typeclasses for monad and functor (we could also add applicative, but that is not necessary for this example):
trait Functor[F[_]] {
def map[A,B](fa: F[A])(f: A => B): F[B]
}
trait Monad[F[_]] extends Functor[F] {
def flatMap[A,B](fa: F[A])(f: A => F[B]): F[B]
def pure[A](x: A): F[A]
}
object Monad {
implicit object ListMonad extends Monad[List] {
def map[A,B](fa: List[A])(f: A => B) = fa map f
def flatMap[A,B](fa: List[A])(f: A => List[B]) = fa flatMap f
def pure[A](x: A) = x :: Nil
}
implicit object OptionMonad extends Monad[Option] {
def map[A,B](fa: Option[A])(f: A => B) = fa map f
def flatMap[A,B](fa: Option[A])(f: A => Option[B]) = fa flatMap f
def pure[A](x: A) = Some(x)
}
def apply[F[_] : Monad]: Monad[F] = implicitly[Monad[F]]
}
Once we have those, we can create the transformer, which basically just wraps the F[List[A]] and forwards the call to its map and flatMap function to the list by calling map on the containing functor and then calling map or flatMap resp. on the contained List/s.
final case class ListT[F[_] : Monad, A](fa: F[List[A]]) {
def map[B](f: A => B) = ListT(Monad[F].map(fa)(_ map f))
def flatMap[B](f: A => ListT[F, B]) = ListT(Monad[F].flatMap(fa) { _ match {
case Nil => Monad[F].pure(List[B]())
case list => list.map(f).reduce(_ ++ _).run
}})
def ++(that: ListT[F,A]) = ListT(Monad[F].flatMap(fa) { list1 =>
Monad[F].map(that.run)(list1 ++ _)
})
def run = fa
}
Once we are done with modifying, we can get the resulting object by calling the run method on the ListT object. If you want, you can also add other list specific operations like in scalaz. This should be pretty straight forward. For example a :: could look as follows:
def ::(x: A) = ListT(Monad[F].map(fa)(x :: _))
Usage:
scala> ListT(Option(List(1,2,3)))
res6: ListT[Option,Int] = ListT(Some(List(1, 2, 3)))
scala> res6.map(_+45)
res7: ListT[Option,Int] = ListT(Some(List(46, 47, 48)))
scala> 13 :: res7
res8: ListT[Option,Int] = ListT(Some(List(13, 46, 47, 48)))
scala> res8.run
res10: Option[List[Int]] = Some(List(13, 46, 47, 48))
I think scalaz.ListT is incorrect in scalaz 7.0.x and 7.1.x.
https://github.com/scalaz/scalaz/issues/921
6.x version is correct. but it is same as StreamT.
I thought PartialFunction can be Monoid. Is my thought process correct ?
For example,
import scalaz._
import scala.{PartialFunction => -->}
implicit def partialFunctionSemigroup[A,B]:Semigroup[A-->B] = new Semigroup[A-->B]{
def append(s1: A-->B, s2: => A-->B): A-->B = s1.orElse(s2)
}
implicit def partialFunctionZero[A,B]:Zero[A-->B] = new Zero[A-->B]{
val zero = new (A-->B){
def isDefinedAt(a:A) = false
def apply(a:A) = sys.error("error")
}
}
But current version Scalaz(6.0.4) is not included it. Is there a reason for something not included ?
Let's shine a different light on this.
PartialFunction[A, B] is isomorphic to A => Option[B]. (Actually, to be able to check if it is defined for a given A without triggering evaluation of the B, you would need A => LazyOption[B])
So if we can find a Monoid[A => Option[B]] we've proved your assertion.
Given Monoid[Z], we can form Monoid[A => Z] as follows:
implicit def readerMonoid[Z: Monoid] = new Monoid[A => Z] {
def zero = (a: A) => Monoid[Z].zero
def append(f1: A => Z, f2: => A => Z) = (a: A) => Monoid[Z].append(f1(a), f2(a))
}
So, what Monoid(s) do we have if we use Option[B] as our Z? Scalaz provides three. The primary instance requires a Semigroup[B].
implicit def optionMonoid[B: Semigroup] = new Monoid[Option[B]] {
def zero = None
def append(o1: Option[B], o2: => Option[B]) = o1 match {
case Some(b1) => o2 match {
case Some(b2) => Some(Semigroup[B].append(b1, b2)))
case None => Some(b1)
case None => o2 match {
case Some(b2) => Some(b2)
case None => None
}
}
}
Using this:
scala> Monoid[Option[Int]].append(Some(1), Some(2))
res9: Option[Int] = Some(3)
But that's not the only way to combine two Options. Rather than appending the contents of the two options in the case they are both Some, we could simply pick the first or the last of the two. Two trigger this, we create a distinct type with trick called Tagged Types. This is similar in spirit to Haskell's newtype.
scala> import Tags._
import Tags._
scala> Monoid[Option[Int] ## First].append(Tag(Some(1)), Tag(Some(2)))
res10: scalaz.package.##[Option[Int],scalaz.Tags.First] = Some(1)
scala> Monoid[Option[Int] ## Last].append(Tag(Some(1)), Tag(Some(2)))
res11: scalaz.package.##[Option[Int],scalaz.Tags.Last] = Some(2)
Option[A] ## First, appended through it's Monoid, uses the same orElse semantics as your example.
So, putting this all together:
scala> Monoid[A => Option[B] ## First]
res12: scalaz.Monoid[A => scalaz.package.##[Option[B],scalaz.Tags.First]] =
scalaz.std.FunctionInstances0$$anon$13#7e71732c
No, this looks good, satisfying both the requirements for (non-commutative) Monoid. Interesting idea. What use case are you trying to support?
Your zero certainly violates the axiom for the identity element, but I think the identity (partial) function would be OK.
Your append also doesn't fulfill the Monoid laws, but instead of orElse you could call andThen (composition). But this would only work for A == B:
implicit def partialFunctionSemigroup[A]: Semigroup[A --> A] = new Semigroup[A --> A] {
def append(s1: A --> A, s2: => A --> A): A-->A = s1 andThen s2
}
implicit def partialFunctionZero[A]: Zero[A --> A] = new Zero[A --> A] {
val zero = new (A --> A) {
def isDefinedAt(a:A) = true
def apply(a:A) = a
}
}