Scala函数中的异构参数

7
我该如何将一些HList作为参数传递?这样我就可以这样做:
def HFunc[F, S, T](hlist: F :: S :: T :: HNil) {
    // here is some code
}

HFunc(HList(1, true, "String")) // it works perfect

但如果我的列表很长,而且我对它一无所知,我该如何在其上执行一些操作? 我如何传递参数而不失去其类型?


1
你想在方法体中执行什么样的操作? - Miles Sabin
嗯,一些类型相关的对象可以存储在这个列表中,我不想丢失关于对象类型的信息。因此,我需要对 HLists 上的所有操作进行处理 - maphead 等等... :) - DaunnC
1个回答

8

这取决于您的使用情况。

HList 对于类型级别的代码非常有用,因此您应该像这样将所有必要的信息一起传递给您的方法,而不仅仅是 HList

def hFunc[L <: HList](hlist: L)(implicit h1: Helper1[L], h2: Helper2[L]) {
    // here is some code
}

例如,如果您想要反转您的Hlist映射结果,您应该像这样使用MapperReverse

import shapeless._, shapeless.ops.hlist.{Reverse, Mapper}

object negate extends Poly1 {
  implicit def caseInt = at[Int]{i => -i}
  implicit def caseBool = at[Boolean]{b => !b}
  implicit def caseString = at[String]{s => "not " + s}
}

def hFunc[L <: HList, Rev <: HList](hlist: L)(
                              implicit rev: Reverse[L]{ type Out = Rev },
                                       map: Mapper[negate.type, Rev]): map.Out =
  map(rev(hlist)) // or hlist.reverse.map(negate)

使用方法:

hFunc(HList(1, true, "String"))
//String :: Boolean :: Int :: HNil = not String :: false :: -1 :: HNil

我看到了,例如:def hFunc[L <: HList](hlist: L)(implicit m: TypeTag[L]),并且在 m 中有关于对象类型的所有信息;但是我无法使用 hlist.head,因为实际上 hlist 参数具有另一种类型;并且它会抛出一个错误(在制作 hlist.head 时):could not find implicit value for parameter c: shapeless.IsHCons[L] - DaunnC
@DaunnC:不要使用TypeTag。你应该使用Mapper来进行map操作,使用Reverse来进行reverse操作等等。 - senia
2
@DaunnC:我猜shapeless的源代码、示例和测试是最好的学习资源。你也可以阅读stackoverflow上的问题。我不知道其他有用的链接。请查看我的答案更新以获取代码示例。 - senia

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接