如何用HList调用多个参数的函数?

时间:2015-07-23 13:30:48

标签: scala shapeless

假设我有HList类型A::B::C::HNil和函数(A, B, C) => D

val hlist: A::B::C::HNil = ???
def foo(a: A, b: B, c: C): D = ???

现在我需要一个功能A::B::C::HNil => D,它使用foo返回D

def bar(hslist: A::B::C::HNil): D = ???

您将如何实施bar

2 个答案:

答案 0 :(得分:9)

您可以使用Shapeless的FnToProduct直接执行此操作,toProduct提供FunctionN语法,用于将Function1转换为HList获取import shapeless._, syntax.std.function._ type A = String type B = Symbol type C = Int type D = List[String] val hlist: A :: B :: C :: HNil = "foo" :: 'x :: 1 :: HNil def foo(a: A, b: B, c: C): D = List.fill(c)(a + b) def bar(hslist: A :: B :: C :: HNil): D = (foo _).toProduct.apply(hslist)

bar

在许多情况下,您甚至可能不想要单独的{{1}}定义。

答案 1 :(得分:2)

您可以使用从HListTuple的无形转换,并将Function.tupled与原始函数一起使用:

def sum(a: Int, b: Int) = a + b

def sumHList(hlist: Int :: Int :: HNil) = {
  val tupledSum = Function.tupled(sum _)
  tupledSum(hlist.tupled)
}

def sumHList2(hlist: Int :: Int :: HNil) = hlist.head + hlist.tail.head

sum(1, 2)
sumHList(1 :: 2 :: HNil)
sumHList2(1 :: 2 :: HNil)
// result from all three = 3