这是我之前question的后续内容。
假设我现在有这样的数据结构:
case class C()
case class B(cs: Seq[C])
case class A(bs: Seq[B])
你会如何写一个函数A => Seq[(A, Option[B], Option[C])]
?
该功能应该像这样工作:
A(Nil) // Seq((Some(A()), None, None))
A(Seq(B(Nil))) // Seq((Some(A()), Some(B()), None))
A(Seq(B(Seq(C())))) // Seq((Some(A()), Some(B()), Some(C()))
monad变压器在这种情况下是否有用?
答案 0 :(得分:1)
我相信这可以满足您的需求 - 基于之前的answer类似问题:
def foo(a: A): Seq[(A, Option[B], Option[C])] =
toOptions(a.bs).flatMap(optB =>
optB
.map(b => toOptions(b.cs))
.getOrElse(Seq(None))
.map(optC => (a, optB, optC))
)
// always returns a non-empty list - with None as the only value for empty input
def toOptions[T](s: Seq[T]): Seq[Option[T]] = s.headOption +: s.drop(1).map(Some(_))
答案 1 :(得分:1)
您的基本map
/ flatMap
组合,并对None
条件进行额外测试。
def unwind(a:A) :Seq[(A, Option[B], Option[C])] = {
if (a.bs.isEmpty) Seq((a,None,None))
else a.bs.flatMap{ b =>
if (b.cs.isEmpty) Seq((a,Some(b),None))
else b.cs.map(c => (a,Some(b),Some(c)))
}
}