我正在学习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是否提供了更简洁的语法,可能没有所有这些下划线?
答案 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
null
和Some
之后,您可以使用scala.Option。映射并使用{{1}执行 - 请参阅讨论此特定示例的scala.Option的scaladoc。
有人可能会提出以下建议:
_.toUpperCase
答案 2 :(得分:0)
可以使构图更紧凑:
使用andThen
要将其简化为下划线(即使包含两个以上的函数):
def upperCaseOrNull = StringUtils.upperCase _ andThen StringUtils.stripToNull
具有三个功能的更一般的情况:
def fgh = h _ andThen g andThen f
使用助手功能
如果f
,g
和h
是带有一个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)
}