是的,你可以
import shapeless._
import shapeless.ops.traversable._
import syntax.std.traversable._
import ops.function._
def fromList[F, I <: HList, O](f: F)(implicit
ftp: FnToProduct.Aux[F, I => O],
ft: shapeless.ops.traversable.FromTraversable[I]): List[Int] => Option[O] =
{ x: List[Int] => x.toHList[I].map(ftp(f)) }
說明
我們使用FnToProduct
任何FunctionN
轉變爲Function1
,它接受一個HList
作爲唯一的參數。
所以,
Int => String ----> Int :: HNil => String
(Int, Int) => String ----> Int :: Int :: HNil => String
...
現在我們抽象了該函數的輸入參數的元數,我們可以簡單地轉換List[Int]
以適合變換函數的輸入的HList
。 爲了執行此轉換,我們需要範圍內的FromTraversable[I]
。
如果一切成功,我們返回並Option[O]
其中O
是該函數的返回類型。 如果輸入List
的形狀不正確,我們只是不能返回None
。
使用
@ val f1: Int => String = _.toString
f1: Int => String = <function1>
@ val f2: (Int, Int) => String = (_, _).toString
f2: (Int, Int) => String = <function2>
@ val fromList1 = fromList(f1)
fromList1: List[Int] => Option[String] = <function1>
@ val fromList2 = fromList(f2)
fromList2: List[Int] => Option[String] = <function1>
@ fromList1(List(1))
res22: Option[String] = Some(1)
@ fromList2(List(1, 2))
res23: Option[String] = Some((1,2))
@ fromList1(List())
res24: Option[String] = None
不是列表,但這個想法是一樣的:https://github.com/milessabin/shapeless/wiki/Feature-overview:-shapeless-2.0.0#facilities-for - 抽象多元性 – dk14