Scala中函数组合的简明语法?

时间:2014-03-14 15:58:48

标签: scala higher-order-functions function-composition

我正在学习Scala并遇到以下任务 - 如果string为空,则返回null,否则为大写。

Apache Commons中有两个功能组合在一起解决了这个问题。在哈斯克尔,我只写:

upperCaseOrNull = StringUtils.stripToNull . StringUtils.upperCase

然而,我无法找到一种在Scala中进行简单易用的功能组合的方法。我找到的最短路径如下:

def upperCaseOrNull (string:String) = StringUtils.stripToNull (StringUtils.upperCase(string))
def upperCaseOrNull = StringUtils.stripToNull _ compose StringUtils.upperCase _

Scala是否提供了更简洁的语法,可能没有所有这些下划线?

3 个答案:

答案 0 :(得分:2)

Haskell是一个极其紧凑的大师,对于它真正关心的一些事情。所以它几乎不可能被击败。如果你做了很多功能组合,那么开销确实会妨碍你(个人而言,重复StringUtils.会让我感到更加困扰!),你可以做类似

的事情。
implicit class JoinFunctionsCompactly[B,C](g: B => C) {
  def o[A](f: A => B) = g compose f
}

所以现在你只有两个额外的字符(_两次)超过Haskell。

答案 1 :(得分:0)

如果涉及null,我不会声称任务很简单。如果Scala中的null会这样做,您为什么需要None?我认为由于null被返回,该功能对组合不是很友好。

转换StringUtils.stripToNull以转换None nullSome之后,您可以使用scala.Option。映射并使用{{1}执行 - 请参阅讨论此特定示例的scala.Option的scaladoc。

有人可能会提出以下建议:

_.toUpperCase

答案 2 :(得分:0)

可以使构图更紧凑:

使用andThen

要将其简化为下划线(即使包含两个以上的函数):

def upperCaseOrNull = StringUtils.upperCase _ andThen StringUtils.stripToNull

具有三个功能的更一般的情况:

def fgh  = h _ andThen g andThen f

使用助手功能

如果fgh是带有一个String参数并返回String的函数:

def fgh = composeMany[String](f, g, h)

composeMany函数如下所示:

def composeManyHelper[T](composed: T => T, funcs: Seq[T => T]): T => T = {
  if (funcs.isEmpty) {
    composed
  } else {
    composeManyHelper[T](funcs.head compose composed, funcs.tail)
  }
}

// Take zero or more functions that take a param of type T and return a value of type T,
// and return a function that is the composition of all the functions
def composeMany[T](funcs: (T => T)*): T => T = {
  composeManyHelper[T](identity[T], funcs.reverse)
}