问题
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?
回答1:
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.
回答2:
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
来源:https://stackoverflow.com/questions/13507202/how-to-use-lift-from-tofunctorops