scala - 从选项中的类型方法生成部分应用的函数

标签 scala partial-application scala-option

假设我正在编写一个 GUI

enter image description here

class Kitteh (val age: Int) {
  require (age < 5)
  def saveMeow(file: File) = { /* implementation */ }
  def savePurr(file: File) = { /* implementation */ }
}

该框架有一个用于当前 Kitteh 的字段,它是一个选项,因为它可能尚未定义,或者用户可能已尝试创建一个无效的:

var currentKitteh: Option[Kitteh] = None

现在我想在用户点击创建时安全地创建一个 Kitteh

val a = ... // parse age from text box
currentKitteh = try { Some(new Kitteh(a)) } catch { case _ => None }

我的 GUI 有两个按钮,它们做类似的事情。在伪代码中,它们都应该

if (currentKitteh.isDefined) {
  if (file on the disk already exists) {
    bring up a dialog box asking for confirmation
    if (user confirms)
       << execute method on currentKitteh >>
  }
}
else bring up warning dialog

不要担心细节:关键是因为存在代码重复,我想创建一个可以从两个按钮调用的通用方法。唯一的区别是需要执行的 Kitteh 上的方法。

现在如果 currentKitteh 不是一个 Option,那么通用方法可以有一个像这样的签名

def save(filename: String, f:(File => Unit)) {

例如,我可以调用它

save("meow.txt", currentKitteh.saveMeow _)

但由于它实际上是一个选项,我该如何实现呢?

我可以只检查是否定义了 currentKitteh,并在为每个按钮调用 save 方法之前执行 .get,但是还有另一种方法,将此检查留在保存 方法?换句话说,给定一个 Option[A],是否可以从(可能不存在的)A 对象的方法中指定部分函数?

(希望这个问题是有道理的,尽管有令人费解的例子)

编辑:奖励问题:如果我使用 Either[Throwable, Kitteh] 而不是 Option[Kitteh] 会怎么样?

update:添加到伪代码中以显示警告对话框的附加行:理想情况下,应始终调用 save 方法,以便在没有有效的情况下警告用户Kitteh 保存。

最佳答案

这对我来说是最好的选择:

currentKitteh foreach { c => save("meow.txt", c.saveMeow _) }

如果你重复这样做,你可以抽象它,

def currentSaveMeow(file: String) = currentKitteh foreach { c =>
  save(file, c.saveMeow _)
}
currentSaveMeow("meow.txt")

我想回答你原来的问题,你也可以将逻辑插入函数参数,

save("meow.txt", file => currentKitten.foreach(_.saveMeow(file)))

此版本的语义略有不同。

更新。如果 k: Option[Kitteh] 被替换为 k: Either[Throwable, Kitteh],那么 k.right foreach { c => ... }?如果您想保留错误信息,您也可以使用 k.right map ...


针对修改后的问题,这里有另一种抽象的可能性,

def save(filename: String, f: (Kitteh, File) => Unit)

现在save负责解包currentKitteh。像这样调用save

save("meow.txt", (k, f) => k.saveMeow(f))

或者像这样,

save("meow.txt", _ saveMeow _)

关于scala - 从选项中的类型方法生成部分应用的函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7354768/

相关文章:

scala - 如何打印在环境变量中使用的依赖 jar ?

scala - 将 Shapeless hlist 类型 F[T1]::...::F[Tn]::HNil 映射到类型 T1::...::Tn::HNil(类型级别排序)

Haskell 美元运算符应用程序

scala - 如何将 scala 中的序列转换/包装为 Option[Seq],以便如果列表为空,则 Option 为 None

generics - Scala 2.10 中的具体泛型

algorithm - 我怎样才能加快我的 Aho-Corasick 算法?

javascript - 关于 Function.prototype.bind() 的困惑

function - 我什么时候必须将我的方法视为 Scala 中的部分应用函数?

scala - 为什么 Option 会扩展 Product?

Scala 应用无法返回选项