在不重载的情况下组合同名的两个函数

Combine two functions under the same name without overloading

代码如下:

 def transform1(f: String => String): Unit = {
    val s = getString
    f.andThen(putString)(s)
  }

  def transform2(f: String => Option[String]): Unit = {
    val s = getString
    f(s).foreach(putString(_))
  }

你如何在一个函数中表达这两个想法? 方法重载不起作用,社区似乎不鼓励。

在描述中添加一个新参数typeOfTransform

在函数内部添加条件

 if (typeOfTransform == type1){ 
 //functionality1
 }else {
 //functionality2
 }

我不明白为什么有人可能想要这个,但这里有一个方法可以做到:

def transform(f: Either[(String => String), (String => Option[String])]: Unit = f match {
   case Left(f) => // do transform1 here
   case Right(f) => //do transform2 here
}

正如我一开始所说,您可能不应该这样做;也许你应该直接问你想要什么。

避免重载的模式是将不同的参数转换为通用的特定类型。可能有任意数量的此类转换。

但是不确定这是最引人注目的示例。

object X {
  trait MapFlat[-A, +B] { def apply(x: A): B }
  implicit class mapper[A](val f: A => A) extends MapFlat[A, A] {
    override def apply(x: A) = {
      val res = f(x)
      println(res)
      res
    }
  }
  implicit class flatmapper[A](val f: A => Option[A]) extends MapFlat[A, Option[A]] {
    override def apply(x: A) = {
      val res = f(x)
      res foreach println
      res
    }
  }
  def f[B](g: MapFlat[String, B]) = {
    g("abc")
  }
}

object Test extends App {
  import X._
  f((s: String) => s)
  f((s: String) => Some(s))
}

一种方法是输入 类,这是一个示例 -

trait Transformer[T] {
  def transform(foo: String => T)
}

object Transformer {

  implicit object StringTransformer extends Transformer[String] {
    override def transform(foo: (String) => String): Unit = ??? // Your logic here
  }

  implicit object OptStringTransformer extends Transformer[Option[String]] {
    override def transform(foo: (String) => Option[String]): Unit = ??? // Your logic here
  }

}

class SampleClass {
  def theOneTransformYouWant[T: Transformer](f: String => T) = {
    implicitly[Transformer[T]].transform(f)
  }

  def canUseBothWays(): Unit = {
    theOneTransformYouWant((s: String) => s)
    theOneTransformYouWant((s: String) => Some(s))
  }
}

另一种方法是磁铁图案 http://spray.io/blog/2012-12-13-the-magnet-pattern/

sealed trait TransformationMagnet {
  def apply(): Unit
}

object TransformationMagnet {
  implicit def fromString(f: String => String): TransformationMagnet =
    new TransformationMagnet {
      def apply(): Unit = ??? // Your code goes here
    }

  implicit def fromOptString(f: String => Option[String]): TransformationMagnet =
    new TransformationMagnet {
      def apply(): Unit = ??? // your code goes here
    }
}


class SampleClass {
  def theOneTransformYouWant(f: TransformationMagnet) = {
    ???
  }

  def hereWeUseItInBothWays(): Unit = {
    theOneTransformYouWant((s: String) => s)
    theOneTransformYouWant((s: String) => Some(s))
  }
}

为了完整起见,您实际上可以通过添加始终可用的隐式参数来重载这样的方法:

def transform(f: String => Option[String]): Unit = ...
def transform(f: String => String)(implicit d: DummyImplicit): Unit = ...