简体   繁体   中英

Using Context Bound with Higher Kinded Type?

Given:

scala> trait Functor[F[_]] { 
  def fmap[A, B](f: A => B, func: F[A]): F[B]
}

and then the something function:

scala> def something[A, B, F[_]](f: A => B, x: A)
                                (implicit ev: Functor[F]): F[B] = 
     |   ev.fmap(f, ???)
something: [A, B, F[_]](f: A => B, x: A)(implicit ev: Functor[F])F[B]

How could I re-write something using Context Bounds for the Functor rather than the implicit ev ... mechanism?

def something[A, B, F[_]](f: A => B, x: A)
                          (implicit ev: Functor[F]): F[B] = 
    ev.fmap(f, ???)

can be rewritten as:

def something[A, B, F[_]: Functor](f: A => B, x: A): F[B] = 
    implicitly[Functor[F]].fmap(f, ???)

This is using the implicitly method from Predef which just asks for an implicit parameter and returns it:

def implicitly[A](implicit a: A): A = a

As an aside, As the other answer points out, you seem to be missing an F[A] , which is perhaps why the second parameter to fmap is ??? , you perhaps want x to be typed F[A] , perhaps you want to change Functor to Applicative so that you can call ev.fmap(f, ev.point(x))

While something 's type is a valid scala type, it is uninhabited, ie a function of that type cannot be implemented, because there is no general way of constructing an F[A] from a given A (of course assuming you don't "cheat", ie null , throw and non-termination are not allowed).

You can of course write the type with context bound syntax, that would be def something[A, B, F[_]: Functor](f: A => B, x: A) . But that won't change the fact that it's uninhabited and thus not very useful.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM