假设我有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
?
答案 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)
您可以使用从HList
到Tuple
的无形转换,并将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