你要的AmazingMalini
签名更改为trait AmazingMalini[F[_], G[_]]
方法,然后可以像这样实现的:
trait AmazingMalini[F[_], G[_]] {
def fMap[A,B](aa: F[G[A]])(f : A => F[G[B]]) : F[G[B]]
}
trait SomeCrazyMagicWithList extends AmazingMalini[Option, List] {
def fMap[A, B](aa: Option[List[A]])(f: A => Option[List[B]]): Option[List[B]] =
aa.flatMap {
_ match {
case Nil => Some(Nil)
case as: List[A] => as.map(f).reduce(concat(_, _))
}
}
def concat[A](x: Option[List[A]], y: Option[List[A]]): Option[List[A]] = for {
xs <- x
ys <- y
} yield xs ++ ys
}
注意Scalaz提供monad transformers,使某些单子的堆叠。例如:
- 的
OptionT
变压器使上的Option
顶部任何单子的堆叠:List[Option[A]]
,Future[Option[A]]
等
- 的
ListT
变压器使上的List
顶部任何单子的堆叠:Option[List[A]]
,Future[List[A]]
。
所以,你的情况,你可以使用ListT
这样的:
import scalaz._
import Scalaz._
import ListT._
listT(List(1,2,3).some).flatMap(i => listT(List(i, i * 3).some))
res0: scalaz.ListT[Option,Int] = ListT(Some(List(1, 3, 2, 6, 3, 9)))
您也可以使用,内涵与单子变压器:
for {
x <- listT(List(1,2).some)
y <- listT(List(3,4).some)
} yield x + y
res2: scalaz.ListT[Option,Int] = ListT(Some(List(4, 5, 5, 6)))
我不知道这是正确的解决方案,但似乎工作:'特质AmazingMalini [F [G],G [_]]','特质SomeCrazyMagicWithList延伸AmazingMalini [Option,List]'。其余代码不变。 –
我会避免使用相同的标识符'G'作为不同的事情,这是相当混乱。换句话说,最好是'AmazingMalini [F [_],G [_]]' –