【问题标题】:Refactor to Higher order function in Scala?在 Scala 中重构为高阶函数?
【发布时间】:2013-02-13 03:35:58
【问题描述】:

学习 Scala 并尝试重构以下两个函数以删除重复的逻辑。我应该创建一个高阶函数还是其他东西以避免重复代码?有更多类似的方法和这样的重复代码,只是在调用不同的域方法上有所不同。

对重构有点困惑。使用 Scala 2.10 版

def authenticate = Action(parse.json) { request =>
  val json = request.body
  val input = Json.fromJson[User](json)
  input.asOpt match {
    case Some(m: User) => Ok(Domain.authenticate(m)).as("application/json")
    case None => Ok("bad input")
  }
}

def addUser = Action(parse.json) { request =>
  val json = request.body
  val input = Json.fromJson[User](json)
  input.asOpt match {
    case Some(m: User) => Ok(Domain.addUser(m)).as("application/json")
    case None => Ok("bad input")
  }
}

【问题讨论】:

  • 一个简单的过程分解(编写一个私有方法来捕获两个方法的公共match 部分)就可以了。

标签: scala


【解决方案1】:

我猜你可以这样做(未经测试):

private def common[A](f:User=>A)(request:RequestHeader) = {
  val json = request.body
  val input = Json.fromJson[User](json)

  input.asOpt match {
    case Some(m: User) => Ok(f(m)).as("application/json")
    case None => Ok("bad input")
  }
}

def addUser = Action(parse.json) { common(Domain.adduser)(_) }

def authenticate = Action(parse.json) { common(Domain.authenticate)(_) } 

【讨论】:

  • 这不会开箱即用。 f 应该是 f: User => A 并且请求应该输入除 Any 之外的其他内容。不过这个想法还可以。
  • 我假设请求对某些东西进行了子分类,因此 Any。如果您有这种类型,我可以对其进行编辑以反映这一点。我认为该请求也可能设置为private def common[A, B](f:User=>A)(request:B) = ...。但是设置它以确保它有一个身体对我来说很棘手。
  • 谢谢。重构成功了,是的 f: is f:User =>A
  • request 在大多数情况下键入为RequestHeader。部分应用的方法有效,但更常见的是将其标记为“隐式”并将操作调整为Action(parse.json) { implicit request => common(Domain.authenticate) }
【解决方案2】:

我也是 Scala 的新手,但我认为我们可以做这样的事情。如果我错了,请纠正我。

你可以这样做

def foo(f:Int=>Int,x:Int):Int = {f(x)}
   foo(x=>x+x,3)

同样,你可以将你想要调用的函数传递给普通函数。

【讨论】:

    猜你喜欢
    • 2021-02-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-07-15
    相关资源
    最近更新 更多