按特定顺序应用功能列表

时间:2013-10-08 15:52:06

标签: scala functional-programming combinatorics

我有一些代表选择的功能,每个选择都有不同的需求。考虑

f1 : Seq[A] => Seq[A]
f2 : Seq[A] => Seq[A]
f3 : Seq[A] => Seq[A]

其中f1f2更合适,f3最不可取。我编写了这个scala代码来生成连续2个选择的结果,从最理想的排序到最小的

def applyTwice[A](initial: Seq[A],
  f1: Seq[A] => Seq[A],
  f2: Seq[A] => Seq[A],
  f3: Seq[A] => Seq[A]): Seq[A] = {

  lazy val f1s = f1(initial).toStream
  lazy val f2s = f2(initial).toStream
  lazy val f3s = f3(initial).toStream

  f1(f1s) ++
    f2(f1s) ++ f1(f2s) ++
    f2(f2s) ++
    f1(f3s) ++ f3(f1s) ++
    f2(f3s) ++ f3(f2s) ++
    f3(f3s)
}

通常,一系列功能应用程序按系列中最差的功能排名。如果最差的是平局,则比较第二个最差,依此类推。例如,f4(f1(a))会比f3(f3(a))更糟糕,因为f4f3更差。请注意,这是f3(f2(a))f2(f3(a))之间的关系。

我可能可以将其推广到可变数量的函数,并且(更难)可变数量的应用程序,但这似乎是一个经典问题,我只是不知道它的名字。这是否已经内置于某些语言/库中?还有更好的方法吗?

1 个答案:

答案 0 :(得分:3)

我不认为这是一个众所周知的事情,但很容易概括:

import scala.math.max
case class Fun[A](cost : Int, fun : Seq[A] => Seq[A])

def applyN[A](funs : Seq[Fun[A]], n : Int, initial : Seq[A]) = 
  (Seq((0, initial)) /: (1 to n)) { 
    case (acc, _) => for {
      f <- funs
      (cost, old) <- acc
    } yield (max(cost, f.cost), f.fun(old))
}
  

阶&GT; val funs = Seq(Fun [Int](2,_. map(_ * 2)),Fun [Int](3,_. map(_ * 3)))

     

funs:Seq [Fun [Int]] = List(Fun(2,),Fun(3,))

     

阶&GT; applyN(funs,2,Seq(1,2,3,4))

     

res0:Seq [(Int,Seq [Int])] = List((2,List(4,8,12,16)),(3,List(6,12,18,24)),( 3,清单(6,12,18,24)),(3,清单(9,18,27,36)))

编辑:我注意到我在这里使用了简化的成本函数,它只是查看最大值,但您可以轻松收集成本列表并应用您想要的任何决定。