ToFunctorOps defines a lift method via the ToLiftV implicit, but I can't seem to make it find my functor instances:
import scalaz.std.option._
import scalaz.syntax.functor._
import scalaz.syntax.id._
import scalaz.syntax.std.option._
def inc(x: Int) = x + 1
1.some |> (inc _).lift
<console>:16: error: could not find implicit value for parameter F: scalaz.Functor[F]
1.some |> (inc _).lift
The functor instance for option is visible but the compiler can't seem to find it. Any suggestions as to how I can fix this?
I don't understand exactly why this isn't working (and I've just asked a follow-up question about the part I don't understand), but I can offer three workarounds.
The first makes no sense to me and requires some deeper changes to your code and clunky syntax, so I'll only mention it in passing.
The second is to import the appropriate FunctorSyntax implicits (as opposed to the ToFunctorOps ones that aren't working properly):
scala> val of = implicitly[scalaz.Functor[Option]]
of: scalaz.Functor[Option] = scalaz.std.OptionInstances$$anon$1#377d4c39
scala> import of.functorSyntax._
import of.functorSyntax._
scala> 1.some |> (inc _).lift
res0: Option[Int] = Some(2)
But this requires you to import these implicits for every individual Functor you want to use them with, and isn't much better than just writing of lift inc.
The last requires a little more code but is more satisfying. You need the following new syntax trait, with a myLift method modeled of the lift in Function2Ops:
trait MyFunction1Syntax[A, R] extends scalaz.syntax.Ops[A => R] {
def myLift[F[_]](implicit F: scalaz.Functor[F]) = F lift self
}
implicit def toMyFunction1Syntax[A, R](f: A => R) =
new MyFunction1Syntax[A, R] { def self = f }
And now you can write the following:
scala> 1.some |> (inc _).myLift
res3: Option[Int] = Some(2)
It might be worth bringing this issue up on the Scalaz mailing list.
Your problem can be easily resolved like this
import scalaz.syntax.std.option._
import scalaz.std.option._
import scalaz.syntax.id._
implicit def liftIt[F[_], A, B](f: A => B)(implicit F: Functor[F]): F[A] => F[B] =
F lift f
def inc(x: Int) = x + 1
2.some |> inc
The issue came from a LiftV trait used in FunctorSyntax. Frankly, I doubt it could have been useful for someone. In order to work, it has to be explicitly typed:
import scalaz.syntax.functor._
val f: LiftV[Option, Int, Int] = (inc _)
2.some |> f.lift
Related
I tried to write a Kleisli.ap function.
final case class Kleisli[F[_], -A, B](run: (A) ⇒ F[B]) extends Product with Serializable
def ap[C, D, AA <: A](f: Kleisli[F, AA, C])(implicit F: Apply[F], ev: As[B, (C) ⇒ D]): Kleisli[F, AA, D]
but
import cats._
import cats.implicits._
import cats.data._
val x: Kleisli[Option,String,Int] = Kleisli(_ => Some(1))
val y: Kleisli[Option,String,Double] = Kleisli(_ => Some(1.0))
val kleisliAp: Kleisli[Option,String,Double] = x.ap(y)
// No implicits found for parameter ev: As[Int, Double => D_]
I saw this error code and looked for a way to create an instance of As[A,B] but could not find one.
Please let me know if you know how to solve this problem.
ap is the wrong way to combine the two objects you have.
ap requires an F[A] and an F[A => B]. You have an F[A] and an F[B]
Instead, use mapN
(x, y).mapN { (int, double) => ??? }
Additionally, ap is considered bad style in scala FP. The shape of it is really not suited to scala; it's there because it's part of the foundation of Apply but mapN is the idiomatic way to compose objects applicatively
I have a list of type List[Result[BigDecimal]] that I want to sum.
type Result[A] = OptionT[Future, A]
The rule would be that if there is any Future(None) then we get the result Future(None).
I have the function [1]:
def sum[A: Monoid](as: List[A]): A = {
val M = implicitly[Monoid[A]]
as.foldLeft(M.zero)(M.append)
}
However, I am missing the Monoid instance for Result[BigDecimal]. How do I define it using Scalaz?
learning Scalaz - sum function
I'm not sure why Scalaz doesn't provide this instance—it does provide a Monoid[Future[A]] where A has a monoid instance, and where there's an implicit execution context in scope. You can easily make your own, though, either by defining an isomorphism between Result and Future[Option[?]] and then using IsomorphismMonoid, or [this wouldn't actually have the desired semantics] by just defining one directly:
import scala.concurrent.ExecutionContext.Implicits.global
import scala.concurrent.Future
import scalaz._, Scalaz._
type Result[A] = OptionT[Future, A]
implicit def resultMonoid[A: Monoid]: Monoid[Result[A]] = new Monoid[Result[A]] {
def zero: Result[A] = Monoid[A].zero.point[Result]
def append(f1: Result[A], f2: => Result[A]): Result[A] = (f1 |#| f2)(_ |+| _)
}
And then (using Scalaz's own suml, but your sum would work as well):
scala> List(OptionT(Future(1.some)), OptionT(Future(2.some))).suml
res1: scalaz.OptionT[scala.concurrent.Future,Int] = OptionT(List())
scala> scala.concurrent.Await.result(res1.run, scala.concurrent.duration.Duration.Inf)
res2: Option[Int] = Some(3)
For what it's worth, Cats provides this instance, but (like the Future[Option[?]] instance in Scalaz) it has None as identity.
I'm trying to make my use of futures as lightweight as possible.
Here is my current test code :
import scala.concurrent.ExecutionContext.Implicits.global
import scala.concurrent.Future
import scala.util.Failure
import scala.util.Success
object Test1 extends App {
def lift[A](a: A): Future[A] = Future { a }
def ap[A, B](fct: Future[A => B], param: Future[A]): Future[B] =
for {
c <- param
o <- fct
} yield (o(c))
implicit def valToFuture[A](elem: A): Future[A] = lift(elem)
implicit class FutureInfix[A, B](val x: Future[A => B]) extends AnyVal {
def <*>(that: Future[A]) = ap(this.x, that)
}
val plus1: Int => Int = (x: Int) => x + 1
val cst1: Int = 1
val extracted: Future[Int] = ap(plus1, cst1)
val extracted2: Future[Int] = lift(plus1) <*> lift(cst1)
val extracted3: Future[Int] = plus1 <*> cst
/*
* - value <*> is not a member of Int ⇒ Int
* - not found: value cst
*/
}
extracted and extracted2 are working but are each using only one of the two implicit conversion I've defined.
extracted3 is what I am aiming at, implicitly lifting plus and cst1 to Future[X] values and converting a <*> b to ap(a,b). But the compiler does not seems to agree with me.
Is what i'm trying to achieve possible ? If so, what do I have to change to make it works ?
PS : This i kind of inspired from what I've seen using haskell.
I think you're bumping up against the "one at a time" rule.
From Programming in Scala, (1st edition):
One-at-a-time Rule: Only one implicit is tried. The compiler will
never rewrite x + y to convert1(convert2(x)) + y. Doing so would cause
compile times to increase dramatically on erroneous code, and it would
increase the difference between what the programmer writes and what
the program actually does. For sanity's sake, the compiler does not
insert further implicit conversions when it is already in the middle
of trying another implicit.
As #tkachuko has pointed out, there likely is a work-around for this limitation using implicit parameters, but one simple solution is to split FutureInfix into two parts.
implicit class FromFutureInfix[A, B](x: Future[A => B]) {
def <*>(that: Future[A]) = ap(x, that)
}
implicit class ToFutureInfix[A, B](x: A => B) {
def <*>(that: A) = ap(x, that)
}
This seems like a simple question that I was sure have been asked before, but couldn't find what I was looking for.
How can one write a function that takes a collection as an argument (or anything that can be treated as a collection), perform some operations on it, and return a collection of the same type?
e.g:
scala> def foo[Repr <% Traversable[String]](repr: Repr) = repr.map(_.size)
foo: [Repr](repr: Repr)(implicit evidence$1: Repr => Traversable[String])Traversable[Int]
this works ok on some collections:
scala> foo(Vector("Hello","World"))
res0: Traversable[Int] = Vector(5, 5)
but surprising when I tried on other collections (e.g. Option):
scala> foo(Some("HelloWorld"))
res1: Traversable[Int] = List(10)
a small problem is the return type Traversable, which ideally would be the type of whatever was given to the method. the bigger problem is the actual implementation type: an Option became a List.
it gets even worse, when tried on classes (that behaves like collections) but have no implicit in scope for them. e.g: Try:
scala> import scala.util._
import scala.util._
scala> foo(Success("HelloWorld"))
<console>:12: error: No implicit view available from scala.util.Success[String] => Traversable[String].
foo(Success("HelloWorld"))
^
So, is there a way, to write a generic function, that when given a "collection like" argument, can operate on it's elements and return the correct type?
ideally, I would like to use it on anything (even Future, and Try) , but for my specific usage, I can do with just real collections & Option.
EDIT:
to illustrate a possible solution, (which forces me to copy&paste code, and so, is not what i'm looking for) is to simply write both functions without view bounds:
scala> :paste
// Entering paste mode (ctrl-D to finish)
def foo[Repr <: Traversable[String]](repr: Repr) = repr.map(_.size)
def foo(repr: Option[String]) = repr.map(_.size)
// Exiting paste mode, now interpreting.
foo: [Repr <: Traversable[String]](repr: Repr)Traversable[Int] <and> (repr: Option[String])Option[Int]
foo: [Repr <: Traversable[String]](repr: Repr)Traversable[Int] <and> (repr: Option[String])Option[Int]
scala> foo(Vector("bar"))
res2: Traversable[Int] = Vector(3)
scala> foo(Some("bar"))
res3: Option[Int] = Some(3)
The concept of mapping is represented by functors. One way to easily provide functor implementations for common classes is to use the scalaz library:
import scala.language.higherKinds
import scalaz.Functor
import scalaz.Scalaz._
def foo[El <: String, Coll[_]](repr: Coll[El])(implicit ev: Functor[Coll]) =
repr.map(_.size)
Now, this just works for List, Vector and Future:
scala> foo(Vector("Hello","World"))
res1: scala.collection.immutable.Vector[Int] = Vector(5, 5)
scala> foo(List("Hello","World"))
res2: List[Int] = List(5, 5)
scala> import scala.concurrent.Future
scala> import scala.concurrent.ExecutionContext.Implicits.global
scala> foo(Future("HelloWorld")) andThen PartialFunction(println(_))
Success(10)
Using it with Some is a bit of a problem, because only Option has a Functor implementation, not Some:
scala> foo(Some("HelloWorld"))
<console>:12: error: could not find implicit value for parameter ev: scalaz.Functor[Some]
foo(Some("HelloWorld"))
^
So you have to provide Option instead of Some to foo:
scala> foo(Some("HelloWorld"): Option[String])
res3: Option[Int] = Some(10)
scala> foo(Option("HelloWorld"))
res4: Option[Int] = Some(10)
scala> foo("HelloWorld".some) // This is from scalaz
res5: Option[Int] = Some(10)
And scalaz doesn't have any typeclass implementations for Try, so if you want to use Functor with Try, you'll have to provide the implementation yourself:
import scala.util.Try
import scalaz.Functor
implicit object TryIsFunctor extends Functor[Try] {
def map[A, B](fa: Try[A])(f: A => B): Try[B] = fa map f
}
Then foo will work with Try, but similar to Option, the argument should have the type Try, instead of Success or Failure:
scala> foo(Try("HelloWorld"))
res9: scala.util.Try[Int] = Success(10)
Also, I believe, there are no Functor implementations in scalaz for more general collection types, like Iterable or Seq.
Out of the common higher-order functions Functor only supports map. So to use flatMap and filter you have to provide different typeclasses instead of Functor. For example, scalaz.Monad supports map and flatMap, and scalaz.MonadPlus supports map, flatMap and filter.
And if you don't want to use scalaz, you'd probably have to make something very similar yourself with typeclasses, to get a good result type instead of Traversable. For example, using CanBuildFrom from the standard library.
I do think Kolmar is right about the general problem, but Scala does support duck-typing, so you can do this:
def foo[T[V]](duck: {def map[U](value: String=>U): T[_]}) ={
duck.map(_.size)
}
foo(Vector("bar")).toVector //> res0: Vector[_$2] = List(3)
foo(Some("bar")) //> res1: Option[_$2] = Some(3)
(toVector just to force the eval of the iterator that otherwise results)
I am not sure how to describe this problem, so I'll just show the type signatures.
I have an instance of the following:
val x:Future[F[Future[F[B]]]] = ???
And I want an instance of:
val y:Future[F[B]] = ???
F is a Monad, so I have the following methods:
def pure[A](a:A):F[A] = ???
def flatMap[A, B](fa:F[A], f:A => F[B]):F[B] = ???
def map[A, B](fa:F[A], f:A => B):F[B] = flatMap(fa, (a:A) => pure(f(a)))
I think the following should work, but it does not feel right:
x.flatMap { fWithFuture =>
val p = Promise[F[B]]
flatMap(fWithFuture, (futureF: Future[F[B]]) => {
p.completeWith(futureF)
pure(())
})
p.future
}
Is there a concept I'm missing?
A bit of background information. I am trying to define a function like this:
def flatMap[A, B](fa:Future[F[A]], f: A => Future[F[B]]):Future[F[B]] = ???
Maybe this is conceptually a weird thing. Any tips on useful abstractions are welcome.
As Rex Kerr notes above, you can often use a monad transformer to deal with a situation where you find yourself with alternating layers like this. For example, if F here is Option, you could use Scalaz 7.1's OptionT monad transformer to write your flatMap:
import scalaz._, Scalaz._
type F[A] = Option[A]
def flatMap[A, B](fa: Future[F[A]], f: A => Future[F[B]]): Future[F[B]] =
OptionT(fa).flatMap(f andThen OptionT.apply).run
OptionT[Future, A] here is a kind of wrapper for Future[Option[A]]. If your F is List, just replace OptionT with ListT and run with underlying (and so on).
The nice thing is that when you're working with OptionT[Future, A], for example, you can generally avoid ending up with Future[Option[Future[Option[A]]]] in the first place—see my answer here for some more detailed discussion.
One drawback is that not all monads have transformers. For example, you can put Future at the bottom of the stack (as I've done above), but there's not really a useful way to define FutureT.
This may answer the "And I want an instance of:" part.
$ scala
Welcome to Scala version 2.10.4 (Java HotSpot(TM) 64-Bit Server VM, Java 1.8.0_05).
Type in expressions to have them evaluated.
Type :help for more information.
scala> import scala.concurrent.Future
import scala.concurrent.Future
scala> import scala.concurrent.ExecutionContext.Implicits.global
import scala.concurrent.ExecutionContext.Implicits.global
scala> Future(List(Future(1),Future(2),Future(3))) // Future[F[Future[B]]]
res0: scala.concurrent.Future[List[scala.concurrent.Future[Int]]] = scala.concurrent.impl.Promise$DefaultPromise#41ab013
scala> res0.map(Future.sequence(_)) // transformed to Future[Future[F[B]]
res1: scala.concurrent.Future[scala.concurrent.Future[List[Int]]] = scala.concurrent.impl.Promise$DefaultPromise#26a4842b
scala> res1.flatMap(identity) // reduced to Future[F[B]]
res2: scala.concurrent.Future[List[Int]] = scala.concurrent.impl.Promise$DefaultPromise#4152d38d
Hopefully the below flatMap definition should give an idea of transforming the types :)
I replaced F with a List type for ease of understanding.
scala> def flatMap[A, B](fa:Future[List[A]], f: A => Future[List[B]]):Future[List[B]] = {
| val x: Future[List[Future[List[B]]]] = fa.map(_.map(f))
| val y: Future[Future[List[List[B]]]] = x.map(Future.sequence(_))
| val z: Future[Future[List[B]]] = y.map(_.map(_.flatten))
| z.flatMap(identity)
| }
flatMap: [A, B](fa: scala.concurrent.Future[List[A]], f: A => scala.concurrent.Future[List[B]])scala.concurrent.Future[List[B]]