scala - 在 Scala 中,如何递归地在单个 Some trait 中构造一个列表?

标签 scala error-handling functional-programming

我现在正在阅读红书“Scala 中的函数式编程”,所以同时我正在学习 Scala。如果我理解正确,特质并不意味着对象。如果我在这里错了,请纠正我。

我的问题是我不知道如何在将 A 类型的列表包裹在 Some 中时构建它。特征。我会很感激正确方向的提示。

在我正在进行的练习中,我被要求定义一个函数,该函数旨在转换列表中的每个元素,然后将整个列表包含在 Some 中。特征。

这是我的代码:

def traverse[A, B](a: List[A])(f: A => Option[B]): Option[List[B]] = a match {
    case Nil => Nil: B
    case h :: t => f(h) flatMap ( hh => hh :: traverse(t)(f))
  }

我觉得我在这里走在正确的轨道上,但是 scala 解释器提示 ::不适用于 Option[List[B]] .我认为这是因为函数的类型签名不返回一个列表,它返回一个包含在 Some 中的 List。

但是我对 的直觉可以吗?平面 map 也有错? f(h)返回 Option[B] .调用 flatmap 实际上会查看 Option 内部,因此 hh 的类型为 B正确的?我的逻辑是这样我可以用函数 hh :: traverse(t)(f) 构造一个 B 类型的列表。 .但我不完全确定是否就在这里。

如果有任何区别,我将使用带有 :paste 命令的 scala 解释器。我不确定这是否会让事情变得更加糟糕。

最佳答案

If I understand correctly, trait does not mean object.



特质就是特质,对象就是对象。 Traits 有点像 Java 中的“接口(interface)”,object s 是单例对象。那些单例对象可以从特征扩展。

Some trait


Some不是特征,而是 class extending Option .

it returns a List wrapped within a Some.



它返回一个包含在 Option 中的列表(即,它可以是 None ,根本没有任何列表)。为了调用::在可选列表值上,您需要另一个 map :
def traverse[A, B](a: List[A])(f: A => Option[B])
: Option[List[B]] = a match {
  case Nil => Some(Nil)
  case h :: t => f(h) flatMap {
    hValue => traverse(t)(f) map {
      tValue => hValue :: tValue
    }
  }
}

您可以缩写为:
def traverse[A, B](a: List[A])(f: A => Option[B])
: Option[List[B]] = a match {
  case Nil => Some(Nil)
  case h :: t => f(h) flatMap {
    hValue => traverse(t)(f) map (hValue :: _)
  }
}

或者只使用 for -立即理解:
def traverse[A, B](a: List[A])(f: A => Option[B])
: Option[List[B]] = a match {
  case Nil => Some(Nil)
  case h :: t => for {
    hValue <- f(h)
    tValue <- traverse(t)(f)
  } yield (hValue :: tValue)
}

关于scala - 在 Scala 中,如何递归地在单个 Some trait 中构造一个列表?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52020871/

相关文章:

Scala 递归函数

scala - 澄清为什么我不能通过它的子类型覆盖使用泛型类参数的方法

scala - 是否可以/建议对 Akka 2 Actor 的不同 child 采取不同的监督策略?

scala - 我的 API 都返回 Future[Option[T]],如何在 for-compr 中很好地组合它们

javascript - React ErrorBoundary - 只是无法让它工作

haskell - 如何在 Haskell 中检查两个文件是否相等

java - 是否有可能在 Stream 中获取下一个元素?

python - TypeError : Cannot treat the value '<function objective_rule at 0x0000000007C31D08>' as a constant because it has unknown type 'function'

perl - 在 Perl 中使用 die 时的退出代码

r - 如何根据 R 中的索引向数据框添加列? (参见示例)