简体   繁体   中英

Difference in Scala between abstracting class versus method

What's the difference in Scala between abstracting the class versus abstracting the method? When use one vs the other?

class lookup[F[_]] {
  def searchUser(username: Username, email: Email): F[Option[User]]
}

object lookup {
  def searchUser[F[_]](username: Username, email: Email): F[Option[User]]
}

Semantics is different for these two cases.

In the first case F is resolved upon creating an instance of the class

class lookup[F[_]] {
  def searchUser(username: Username, email: Email): F[Option[User]] = ???
}

val l1 = new lookup[Future]
val l2 = new lookup[List]
l1.searchUser(username1, email1): Future[Option[User]]
l2.searchUser(username2, email2): List[Option[User]]

In the second case F is resolved upon method call

object lookup {
  def searchUser[F[_]](username: Username, email: Email): F[Option[User]] = ???
}

lookup.searchUser[Future](username1, email1): Future[Option[User]]
lookup.searchUser[List](username2, email2): List[Option[User]]

Suppose you will add one more method

class lookup[F[_]] {
  def searchUser(username: Username, email: Email): F[Option[User]] = ???
  def deleteUser(user: User): F[Unit] = ???
}

Here you know that F is the same for both methods. But for

object lookup {
  def searchUser[F[_]](username: Username, email: Email): F[Option[User]] = ???
  def deleteUser[F[_]](user: User): F[Unit] = ???
}

F in one method and F in another method can be different.

Also lookup[F[_]] can be used in implicits / type classes / context bounds (this is useful in tagless final approach)

def foo[F[_]: lookup] = ???
def foo[F[_]](implicit l: lookup[F]) = ???

while in the second case you lose this ability.

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