假设我有一些功能:
val f1: Int => String
val f2: (Int, Int) => String
val f3: (Int, Int, Int) => String
def fromList1(f: Int => String): List[Int] => Option[String] =
_ match {case x::_ => Some(f(x)); case _ => None}
def fromList2(f: (Int, Int) => String): List[Int] => Option[String] =
_ match {case x::y::_ => Some(f(x, y)); case _ => None}
Run Code Online (Sandbox Code Playgroud)
现在我想编写一个通用工具fromList如下:
val g1: List[Int] => String = fromList(f1) // as fromList1(f1)
val g2: List[Int] => String = fromList(f2) // as fromList2(f2)
Run Code Online (Sandbox Code Playgroud)
我可以这样做shapeless吗?
这可能会有所帮助:
import shapeless._
import syntax.std.traversable._
import shapeless.ops.traversable._
import syntax.std.function._
import ops.function._
def fromList[F, L <: HList, R](f: F)
(implicit fp: FnToProduct.Aux[F, L => R], tr: FromTraversable[L]) =
(p: List[Int]) => p.toHList[L] map f.toProduct
Run Code Online (Sandbox Code Playgroud)
f.toProduct将常规函数转换为以HList参数为参数的函数 - 它需要FnToProduct隐式并且实际上只是调用它。是从 dunction 、 hlist type和 result typeFnToProduct.Aux创建的构造函数(由宏生成)。所有这些都是根据您传递的参数推断出来的。FnToProductFHListRf
最后一个,如果可能的话从常规toHList创建,否则 - 。它使用隐式来做到这一点,其中已经从 推断出。Shapeless2 足够聪明,可以识别(因为可能存在隐式转换)。 Some(HList)ListNoneFromTraversable[L]LfHListTuple
例子:
scala> val f1: Int => String = _ => "a"
f1: Int => String = <function1>
scala> val f2: (Int, Int) => String = (_, _) => "a"
f2: (Int, Int) => String = <function2>
scala> val g1 = fromList(f1)
g1: List[Int] => Option[String] = <function1>
scala> g1(List(1))
res6: Option[String] = Some(a)
scala> val g2 = fromList(f2)
g2: List[Int] => Option[String] = <function1>
scala> g2(List(1, 2))
res7: Option[String] = Some(a)
scala> g2(List(1))
res8: Option[String] = None
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
254 次 |
| 最近记录: |