2

with Cats, I can write this simple program

def foo(x: Int) = x + 1
val bar = Functor[Future](foo)

and Now I can do a bar(future(1)) and get a Future.Success(2) as a result. Very good.

But suppose my function was

def foo[T](x: T)(implicit m: Manifest[T]) : String = {...}

Now if I try to lift this function

def futureFoo = Functor[Future].lift(foo)

I get a compiler error No Manifest available for T.

So how do I lift this function?

I searched and found this thread (which is for scalaz)

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

But I still couldn't create anything which worked for me. I tried

val futureFoo = Functor[T].lift2(foo[T] _)

but this doesn't compile

Community
  • 1
  • 1
Knows Not Much
  • 30,395
  • 60
  • 197
  • 373

1 Answers1

3

Functions in Scala cannot have implicit parameters, so when you try to eta-expand a method with an implicit parameter into a function, the implicit needs to be resolved before the function itself is applied. That is, at the time of eta-expansion. The compiler doesn't have a generic Manifest[T] in scope, but futureFoo can require one.

def foo[T](x: T)(implicit m: Manifest[T]) : String = ""

scala> def optionFoo[T: Manifest] = Functor[Option].lift(foo[T] _)
optionFoo: [T](implicit evidence$1: Manifest[T])Option[T] => Option[String]

I used Option because I didn't have a Functor[Future] readily available, the the same concept applies. Note that in order to use this, you'll need to supply the type parameter manually for it to return the correct function.

scala> optionFoo[Int].apply(Option(1))
res2: Option[String] = Some()
Michael Zajac
  • 55,144
  • 7
  • 113
  • 138