7

How can I pass some HList as an argument? So I can make in a such way:

def HFunc[F, S, T](hlist: F :: S :: T :: HNil) {
    // here is some code
}

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

But if I have a long list, and I dunno nothing about it, how can I make some operations on it? How can I pass argument and not to loose its type?

DaunnC
  • 1,301
  • 15
  • 30
  • 1
    What sort of operations do you want to perform in the method body? – Miles Sabin Oct 28 '13 at 12:12
  • hm, some type dependent objects can be stored in this list, and I want not to lose information about object types. So I need mb all operations on `HLists` - `map, head, etc...` :) – DaunnC Oct 28 '13 at 12:24

1 Answers1

8

It depends on your use-case.

HList is useful for type-level code, so you should pass to your method not only HList, but also all necessary information like this:

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

For instance if you want to reverse your Hlist and map over result you should use Mapper and Reverse like this:

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)

Usage:

hFunc(HList(1, true, "String"))
//String :: Boolean :: Int :: HNil = not String :: false :: -1 :: HNil
senia
  • 37,745
  • 4
  • 88
  • 129
  • y, I see, for example: `def hFunc[L <: HList](hlist: L)(implicit m: TypeTag[L])` and there is all information about object type in `m`; but I can't make `hlist.head`, cause in fact `hlist` argument has another type; and it throws an error (on making `hlist.head`): `could not find implicit value for parameter c: shapeless.IsHCons[L]` – DaunnC Oct 28 '13 at 12:34
  • @DaunnC: Not `TypeTag`. You should use `Mapper` for `map`, `Reverse` for `reverse` and so on. – senia Oct 28 '13 at 12:38
  • 2
    @DaunnC: I guess [shapeless](https://github.com/milessabin/shapeless) source, example and tests are best learning resources. You could also read stackoverflow [questions](http://stackoverflow.com/questions/tagged/shapeless?sort=votes&pageSize=50). I don't know other useful links. See update in my answer for code example. – senia Oct 28 '13 at 13:01