Creating a WriterT[F, W, A] from a Writer[W, A] - scala

In Scalaz, is there an easy way to convert an instance of Writer[W, A] (which is an alias for WriterT[Id, W, A]) to WriterT[F, W, A]?
I'm looking for something similar to the optionT function combined with point, but for writers instead:
E.g.
// Similar situation, but using OptionT
val opt: Option[String] = Some("log")
val optT: OptionT[IO, String] = optionT(opt.point[IO])
// Case in hand, using WriterT
val w: Writer[String, Unit] = "log".tell
val wt: WriterT[IO, String, Unit] = ???
// Similar scenario
val w: Writer[String, Int] = 3.set("log")
val wt: WriterT[IO, String, Int] = ???

Some monadic types have lift methods that help with this kind of operation:
import scalaz._, Scalaz._, effect.IO
val stateIO: StateT[IO, Int, Unit] = put(10).lift[IO]
Writer doesn't, but you can use the Hoist instance for WriterT to accomplish the same thing:
type StringWriter[F[_], A] = WriterT[F, String, A]
def fromId[F[_]: Applicative]: Id ~> F = new (Id ~> F) {
def apply[A](a: A) = a.point[F]
}
val w: Writer[String, Unit] = "log".tell
val wt: WriterT[IO, String, Unit] = Hoist[StringWriter].hoist(fromId[IO]).apply(w)
This isn't terribly convenient, but that's something you have to get used to when working with monad transformers.

Related

Why scala cannot resolve the T parameter

When I try to call the following function:
def sortBy[T, R](seq: Seq[T], by: T => R)(implicit ordering: Ordering[R]): Seq[T] = {
...
}
with this:
case class MyClass(f1: Int, f2: Int)
val o1 = MyClass(1, 2)
val o2 = MyClass(3, 4)
sortBy(Seq(o1, o2), x => x.f1)
I get compilation error "cannot resolve symbol f1"
However when I call it with explicit types it works:
sortBy[MyClass,Int](...)
My question is why scala cannot infer these types automatically?
As one of the ways to solve
def sortBy[T, R](seq: Seq[T], by: T => R)(implicit ordering: Ordering[R]): Seq[T] = ???
case class MyClass(f1: Int, f2: Int)
val o1 = MyClass(1, 2)
val o2 = MyClass(3, 4)
def orderFunc(a: MyClass): Int = a.f1
sortBy(Seq(o1, o2), orderFunc)

Scala cats, traverse Seq

I know I can traverse Lists
import cats.instances.list._
import cats.syntax.traverse._
def doMagic(item: A): M[B] = ???
val list: List[A] = ???
val result: M[List[B]] = list.traverse(doMagic)
And I can convert a Seq back and forth to List
val seq: Seq[A] = ???
val result: M[Seq[B]] = seq.toList.traverse(doMagic).map(_.toSeq)
But can I also traverse Seq without the boilerplate?
val seq: Seq[A] = ???
val result: M[Seq[B]] = seq.traverse(doMagic)
Or what's an easy way to get an instance of Traverse[Seq]?
Cats does not provide typeclass instances for Seq, so besides implementing it yourself you're stuck with the conversion.
As to why, there's an ongoing discussion in an (somewhat old) Cats issue. To sum it up, you won't know enough about Seq underlying characteristics to make sure some of the typeclasses instances laws hold.
EDIT : Nevermind, it exists now, see linked thread
As of cats 2.3, support for immutable.Seq is now built in. See "Where are implicit instances for Seq?" on the FAQ or this PR where the functionality was added.
If you are absolutely sure that the conversion from all Seq to List will always succeed in your code, you can simply transfer the Traverse structure from List to Seq over an (pseudo-)isomorphism:
def traverseFromIso[F[_], Z[_]]
(forward: F ~> Z, inverse: Z ~> F)
(implicit zt: Traverse[Z])
: Traverse[F] = new Traverse[F] {
def foldLeft[A, B](fa: F[A], b: B)(f: (B, A) ⇒ B): B = zt.foldLeft(forward(fa), b)(f)
def foldRight[A, B](fa: F[A], lb: Eval[B])(f: (A, Eval[B]) => Eval[B]): Eval[B] =
zt.foldRight(forward(fa), lb)(f)
def traverse[G[_], A, B]
(fa: F[A])
(f: (A) ⇒ G[B])
(implicit appG: Applicative[G])
: G[F[B]] = {
(zt.traverse(forward(fa))(f)(appG)).map(zb => inverse(zb))
}
}
This isn't really an isomorphism, because the conversion from Seq to List can fail badly (e.g. if the sequence is infinite). What it does is simply converting Seq to List back and forth, and forwarding all method calls to those of Traverse[List].
Now you can use this method to build an instance of Traverse[Seq]:
implicit val seqTraverse: Traverse[Seq] = traverseFromIso(
new FunctionK[Seq, List] { def apply[X](sx: Seq[X]): List[X] = sx.toList },
new FunctionK[List, Seq] { def apply[X](lx: List[X]): Seq[X] = lx }
)
Full code snippet (compiles with scala 2.12.4 and cats 1.0.1):
import cats._
import cats.implicits._
import cats.arrow.FunctionK
import scala.language.higherKinds
object TraverseFromIso {
// This method can build you a `Traversable[Seq]` from
// an `Traversable[List]` and a pair of polymorphic conversion
// functions:
def traverseFromIso[F[_], Z[_]]
(forward: F ~> Z, inverse: Z ~> F)
(implicit zt: Traverse[Z])
: Traverse[F] = new Traverse[F] {
def foldLeft[A, B](fa: F[A], b: B)(f: (B, A) ⇒ B): B = zt.foldLeft(forward(fa), b)(f)
def foldRight[A, B](fa: F[A], lb: Eval[B])(f: (A, Eval[B]) => Eval[B]): Eval[B] =
zt.foldRight(forward(fa), lb)(f)
def traverse[G[_], A, B]
(fa: F[A])
(f: (A) ⇒ G[B])
(implicit appG: Applicative[G])
: G[F[B]] = {
(zt.traverse(forward(fa))(f)(appG)).map(zb => inverse(zb))
}
}
// A little demo
def main(args: Array[String]): Unit = {
// To instantiate a `Traverse[Seq]`, we have to provide
// two natural transformations (from List to Seq and back):
implicit val seqTraverse: Traverse[Seq] = traverseFromIso(
new FunctionK[Seq, List] { def apply[X](sx: Seq[X]): List[X] = sx.toList },
new FunctionK[List, Seq] { def apply[X](lx: List[X]): Seq[X] = lx }
)
// do stuff with `Traversable[Seq]` here
}
}

Flattening Future[EitherT[Future, A, B]]

As the title mentions.
Having many operations done using EitherT[Future, A, B]. Sometimes I want map left or right through another operation having signature A => Future[C]. Other scenario is that EitherT[Future, A, B] the result of a mapping over a future resulting Future[EitherT[Future, A, B]].
How can I elegantly flatten types like:
EitherT[Future, Future[A], Future[B]] and Future[EitherT[Future, A, B]]
Thank you in advance.
In all your cases you can use EitherT#flatMap (or EitherT#flatMapF), in combination with lifting some value to EitherT (or disjunction (\/) with flatMapF).
Mapping a B => F[C] over an EitherT[F, A, B] :
flatMap + lift
import scala.concurrent.Future
import scala.concurrent.ExecutionContext.Implicits.global
import scalaz._, Scalaz._
def f(i: Int): Future[Double] = Future.successful(i.toDouble)
val r = EitherT.right[Future, String, Int](Future.successful(1))
r.flatMap(i => EitherT.right(f(i)))
// or
r.flatMapF(i => f(i).map(_.right))
Mapping a A => F[C] over an EitherT[F, A, B] :
swap + flatMap + lift
def g(s: String): Future[Int] = Future.successful(s.length)
val l = EitherT.left[Future, String, Int](Future.successful("error"))
l.swap.flatMap(s => EitherT.right(g(s))).swap
// or
l.swap.flatMap(s => EitherT.left[Future, Int, Int](g(s)))
// or
l.swap.flatMapF(s => g(s).map(_.left))
Mapping an A => Either[F, B, C] to an F[A] :
lift + flatMap
def h(i: Int): EitherT[Future, String, Int] =
EitherT.right(Future.successful(i + 1))
val fut = Future.successful(1)
// mapping gives us Future[EitherT[Future, String, Int]]
fut.map(h)
// lifting to EitherT and flatMap gives us EitherT[Future, String, Int]
EitherT.right(fut).flatMap(h)

Lifting a function which takes implicit parameter using functor (Scalaz7)

Just started learning Scalaz. Here is my code
trait Monoid[A] {
def mappend(a1: A, a2: A): A
def mzero: A
}
object Monoid {
implicit val IntMonoid: Monoid[Int] = new Monoid[Int] {
def mappend(a1: Int, a2: Int): Int = a1 + a2
def mzero: Int = 0
}
implicit val StringMonoid: Monoid[String] = new Monoid[String] {
def mappend(a1: String, a2: String): String = a1 + a2
def mzero: String = ""
}
}
trait MonoidOp[A] {
val F: Monoid[A]
val value: A
def |+|(a2: A): A = F.mappend(value, a2)
}
object MonoidOp{
implicit def toMonoidOp[A: Monoid](a: A): MonoidOp[A] = new MonoidOp[A]{
val F = implicitly[Monoid[A]]
val value = a
}
}
I have defined a function (just for the sake of it)
def addXY[A: Monoid](x: A, y: A): A = x |+| y
I want to lift it so that it could be used using Containers like Option, List, etc. But when I do this
def addXYOptioned = Functor[Option].lift(addXY)
It says error: could not find implicit value for evidence parameter of type scalaz.Monoid[A]
def addOptioned = Functor[Option].lift(addXY)
How to lift such functions?
Your method addXY needs a Monoid[A] but there is no Monoid[A] in scope when used in addXYOptioned, so you also need to add the Monoid constraint to addXYOptioned.
The next problem is that Functor.lift only lifts a function A => B, but we can use Apply.lift2 to lift a function (A, B) => C.
Using the Monoid from Scalaz itself :
import scalaz._, Scalaz._
def addXY[A: Monoid](x: A, y: A): A = x |+| y
def addXYOptioned[A: Monoid] = Apply[Option].lift2(addXY[A] _)
We could generalize addXYOptioned to make it possible to lift addXY into any type constructor with an Apply instance :
def addXYApply[F[_]: Apply, A: Monoid] = Apply[F].lift2(addXY[A] _)
addXYApply[List, Int].apply(List(1,2), List(3,4))
// List[Int] = List(4, 5, 5, 6)
addXYApply[Option, Int].apply(1.some, 2.some)
// Option[Int] = Some(3)

Converting a List to a Case Class

As an exercise, I am trying to see if I can take a List[Any] and "cast" it into a case class using shapeless.
A very basic example of what I am trying to achieve:
case class Foo(i: Int, j: String)
val foo: Option[Foo] = fromListToCaseClass[Foo]( List(1:Any, "hi":Any) )
Here is how I am shaping my solution (this can be quite off):
def fromListToCaseClass[CC <: Product](a: List[Any]): Option[CC] = a.toHList[???].map( x => Generic[CC].from(x) )
Here is my reasoning:
I know that you can go from a case class to an HList[T] (CC -> HList[T]); where T is the type of the HList. I also know that you can create an HList from a list (list -> Option[HList]) as long as you know the type of the HList. Finally I know that you can go from an HList to a case class (HList -> CC).
CC -> HList[T]
list -> Option[HList[T]] -> Option[CC]
I am wondering if this makes sense or if I am way off here. Can we make this work? Any other suggestions? Thanks!
This can be done very straightforwardly using shapeless's Generic and FromTraversable type classes,
import scala.collection.GenTraversable
import shapeless._, ops.traversable.FromTraversable
class FromListToCaseClass[T] {
def apply[R <: HList](l: GenTraversable[_])
(implicit gen: Generic.Aux[T, R], tl: FromTraversable[R]): Option[T] =
tl(l).map(gen.from)
}
def fromListToCaseClass[T] = new FromListToCaseClass[T]
(There's some accidental complexity here due to Scala's awkwardness when it comes to mixing explicit and inferred type parameters: we want to specify T explicitly, but have R inferred for us).
Sample REPL session ...
scala> case class Foo(i: Int, j: String)
defined class Foo
scala> fromListToCaseClass[Foo](List(23, "foo"))
res0: Option[Foo] = Some(Foo(23,foo))
scala> fromListToCaseClass[Foo](List(23, false))
res1: Option[Foo] = None
You can do it with shapeless the following way:
import shapeless._
trait Creator[A] { def apply(list:List[Any]): Option[A] }
object Creator {
def as[A](list: List[Any])(implicit c: Creator[A]): Option[A] = c(list)
def instance[A](parse: List[Any] => Option[A]): Creator[A] = new Creator[A] {
def apply(list:List[Any]): Option[A] = parse(list)
}
def arbitraryCreate[A] = instance(list => list.headOption.map(_.asInstanceOf[A]))
implicit val stringCreate = arbitraryCreate[String]
implicit val intCreate = arbitraryCreate[Int]
implicit val hnilCreate = instance(s => if (s.isEmpty) Some(HNil) else None)
implicit def hconsCreate[H: Creator, T <: HList: Creator]: Creator[H :: T] =
instance {
case Nil => None
case list => for {
h <- as[H](list)
t <- as[T](list.tail)
} yield h :: t
}
implicit def caseClassCreate[C, R <: HList](
implicit gen: Generic.Aux[C, R],
rc: Creator[R]): Creator[C] =
instance(s => rc(s).map(gen.from))
}
And
val foo:Option[Foo] = Creator.as[Foo](List(1, "hi"))