如何使用可以通过 flatmap 链接的错误标记标记(如 Option.None)构造 Scala API?

how to construct Scala API with error sentinel token (like Option.None) that can be chained through flatmap?

我最近尝试了一些并发练习的变体 Functional Programming in Scala (great book, btw.. and early access edition is downloadable free!). Chapter 7 involves creating a monadic type constructor Par[X], which enables any expression of type X to be forked off and run in parallel when paired with an ExectutorService

我尝试的变体是创建一个 API 允许调用者将并行表达式(参数化类型 Par[X] 的实例)平面映射在一起。我想要一些与 Option/Some/None 类似的东西,其中如果链中的平面图结果之一恰好失败(在 Option 的情况下为 'None'),那么该失败 'bubbles up' 到顶部,这样构建链的调用者只需要检查顶级 return 值不是错误哨兵。 (希望从这个解释中我想做的很清楚)。无论如何...我 运行 遇到了构建错误哨兵的问题。

我尝试以两种方式构造它,作为案例对象,以及作为案例 class。在第一个实例中,案例对象,我得到了这个错误

    Object creation impossible since member get():V in java.util.concurrent.future is not defined.

这是第一种情况的代码:

    case object Failure extends Future[Nothing] {
    def isDone = true

    // why is compiler telling me i'm not defining this, when def'n is below?
    def get(timeout: Long, units: TimeUnit) =  
        throw new NoSuchElementException("nothing to get from failure")

    def isCancelled = false

    def cancel(evenIfRunning: Boolean): Boolean = false
    }

然后我尝试使用从 Future[Nothing] 扩展的案例 class,像这样:

  case class Failure2 extends Future[Nothing] {
    def isDone = true

    def get(timeout: Long, units: TimeUnit) =  throw new NoSuchElementException("nothing to get from failure")

    def isCancelled = false

    def cancel(evenIfRunning: Boolean): Boolean = false
  }

这导致了以下错误:

class Failure2 must be declared abstract or implement abstract member get():V in java.util.concurrent.future 

如果你们中的任何专家 Scala API 构建者可以帮助指导我找到解决方案,我将不胜感激!

当错误信息参考

member get():V in java.util.concurrent.Future

他们指的是 the get() method of Future with no arguments,您确实忘记实施了。我猜你想让 get() 的两个版本做同样的事情。您只需要明确说明即可。例如:

def get() = throw ...
def get(timeout: Long, units: TimeUnit) = get()

这个回答补充了 Dan 的回答,他在回答中指出了我的错误(谢谢,Dan!)。我希望这个 answer/comment 可以帮助其他人避免被类似的咬伤。当我编写 'Failure' 案例 class/object 时,我正在查看原始代码库中的一个案例 class,它以一种不明显的方式实现了 Future 的无参数 get()大部头书。这是代码:

      private case class UnitFuture[A](get: A) extends Future[A] {
        def isDone = true

        def get(timeout: Long, units: TimeUnit) = get

        def isCancelled = false

        def cancel(evenIfRunning: Boolean): Boolean = false
      }

在这段代码中,无参数 get() 方法似乎是隐式实现的,因为 get 是 case class 构造函数的参数...我什至没有意识到这个方法存在,所以我忽略了在我的 Failure class 中实现它(因此我遇到了错误方法)。如果我聪明的话,我会直接去 Future 的 javadoc 看看需要什么方法....但是我基于我对 'UnitFuture' class 需要什么的假设,我错过了事实上,没有 arg get() 是 class 的一部分。好吧..边学边学;^) 希望这能帮助其他人不要重蹈我的覆辙。