The Problem
我有两个类如下所示:
class Now {
def do[A](f: Int => A): Seq[A]
}
class Later {
def do[A](f: Int => A): Future[Seq[A]]
}
两个类之间的唯一区别是,Now返回Seq,稍后返回Future Seq . 我希望这两个类共享相同的接口
What I Have Tried
考虑到Seq和Future [Seq]如何只需要一个类型参数,这似乎非常适合高等级的类型 .
trait Do[F[_]] {
def do[A](f: Int => A): F[A]
}
// Compiles
class Now extends Do[Seq] {
def do[A](f: Int => A): Seq[A]
}
// Does not compile. "type Seq takes type parameters" and
// "scala.concurrent.Future[<error>] takes no type parameters, expected: one"
class Later extends Do[Future[Seq]] {
def do[A](f: Int => A): Future[Seq[A]]
}
我错误地使用了更高级的类型吗?我错误地提供了Future [Seq]吗?有没有办法允许Now和Later共享相同的界面?
3 回答
你需要类型组成:
或者如果你只需要在这一个地方
见scalaz(我本可以发誓它包括一般类型的组合,但显然不是 . )
I 相信你想要这个:
但是如果你想要更通用的东西,抽象方法在其返回类型中是完全通用的,那么@AlexeyRomanov的类型组合答案就是你正在寻找的 .
阿列克谢的解决方案非常聪明,可以回答你提出的问题 . 但是,我认为你提出了问题 .
您从这两个接口开始:
并想要修改
Later
所以它实现了这个:但是,你在这里失去了一个机会来抽象出现在或之后的某些事情 . 您应该改为
Do
如下:并将
Now
更改为:这里,Need是一个Scalaz monad,它基本上就像它所包含的对象的惰性身份 . 同样有其他选择,但重点是你需要知道的关于
Future
和Need
的唯一事情是它们是monad . 你对待它们是一样的,你决定在其他地方使用其中一个 .