gpt4 book ai didi

scala - 用于列表、选项和其他复杂类型的高级类型 scala

转载 作者:行者123 更新时间:2023-12-01 11:29:47 25 4
gpt4 key购买 nike

我仍在学习 Scala - 如果这很容易完成,请原谅我。我对 Scalaz 或 Shapeless 也不是很流利——我才刚刚开始探索这些库。我正在某处寻找一篇简单的论文,向我解释如何做类似的事情

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]] = ???
}

请注意,选项或列表类型只是示例,我有几个容器类型,我会在脑海中替换它们(为应用程序构建像 DSL 一样的小型图形遍历)。

最佳答案

您必须将 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启用某些单子(monad)的堆叠。例如:

  • OptionT 转换器可以在 Option 之上堆叠任何 monad:List[Option[A]]Future[选项[A]]
  • ListT 转换器支持在 List 之上堆叠任何 monad:Option[List[A]]Future[列表[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-comprehensions 与 monad 转换器一起使用:

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)))

关于scala - 用于列表、选项和其他复杂类型的高级类型 scala,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33519982/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com