将多个转换函数应用于字符串

时间:2015-06-04 01:54:36

标签: scala

假设我有两种方法:

def a(s: String) = s + "..."

def b(s: String) = s + ",,," 

我想创建第三种方法,它将调用两种方法:

def c (s: String) = a(b(s))

我如何用惯用的Scala方式做到这一点?

我认为最好将这些函数聚合到某个List中,然后依次应用它们:

List(a_, b_)

5 个答案:

答案 0 :(得分:3)

  

我认为最好将这些功能聚合到一些List和   然后依次应用它们。

通过指定预期类型,您可以获得一些帮助:

scala> val fs: List[String => String] = List(a,b)
fs: List[String => String] = List(<function1>, <function1>)

scala> fs.foldLeft("something")((s,f) => f(s))
res0: String = something...,,,

答案 1 :(得分:2)

以下是如何将一组功能组合成一个:

// a() and b() are as defined in the question 
// the following is equivalent to newfunc(x) = b(a(x))   
val newFunc: String => String = List( a _, b _).reduce( _ andThen _ )

您甚至可以创建一个通用函数来组合它们:

def functionChaining[A]( functions: A => A *): A => A = functions.reduce( _ andThen _ )

或使用foldLeft

def functionChaining[A]( functions: A => A *): A => A  = functions.foldLeft( (x:A) => x )( _ andThen _ )

以下是如何在REPL上使用它的示例:

scala> val newFunc: String => String = functionChaining( (x:String) => x + "---", (x:String) => x * 4)
scala> newFunc("|")
res12: String = |---|---|---|---

答案 2 :(得分:1)

许多答案都使用andThen,但这会给你

b(a(s))

鉴于你想要

a(b(s))

compose是要走的路(好吧,或者反转清单,但重点是什么?)

def c(s: String) = List[String => String](a, b).reduce(_ compose _)(s)
// or alternatively
def c(s: String) = List(a _, b _).reduce(_ compose _)(s)

结果

c("foo") // foo,,,...

现在,谈到什么是惯用语,我相信

a(b(s))

更具惯用性和可读性
List(a _, b _).reduce(_ compose _)(s)

这显然取决于你正在编写的功能的数量。如果你有

a(b(c(d(e(f(g(h(s))))))))

然后

List[String => String](a, b, c, d, e, f, g, h).reduce(_ compose _)(s)

可能更整洁,更具惯用性。

答案 3 :(得分:0)

如果确实认为你需要这样做:

val c = a _ andThen b

// (The signature is:)
val c:(String)=>String = a _ andThen b

或者,更明显的是:

def d(s:String) = a _ andThen b

答案 4 :(得分:0)

如果首选链接应用程序,则以下工作原理。警告 - 隐含的语法有点难看;这是一种结构类型,使用反射。

object string {
  implicit def aPimp(s: String) = new {
    def a = "(a- " + s + " -a)"
  }
  implicit def bPimp(s: String) = new {
    def b = "(b- " + s + " -b)"
  }
}

scala> import string._
scala> "xyz".a.b
res0: String = (b- (a- xyz -a) -b)
scala> "xyz".b.a
res1: String = (a- (b- xyz -b) -a)

在我看来,如果不是因为丑陋的语法,这将是惯用的scala。