2013-10-28 5 views
7

Как передать HList в качестве аргумента? Так что я могу сделать в таком виде:Неоднородные аргументы в функции Scala

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

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

Но если у меня есть длинный список, и я не знаю ничего об этом, как я могу сделать некоторые операции на нем? Как передать аргумент и не потерять его тип?

+1

Какие операции вы хотите выполнять в теле метода? –

+0

hm, некоторые типы зависимых объектов могут быть сохранены в этом списке, и я не хочу терять информацию о типах объектов. Поэтому мне нужно mb все операции над 'HLists' -' map, head и т. Д. ':) – DaunnC

ответ

8

Это зависит от вашего прецедента.

HList полезно для кода типа уровня, так что вы должны передать в ваш метод не только HList, но и вся необходимая информация, как это:

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

Например, если вы хотите reverse ваш Hlist и map более результате вы должны использовать Mapper и Reverse так:

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 
+0

y, я вижу, например:' def hFunc [L <: HList] (hlist: L) (неявный m: TypeTag [L]) 'и вся информация о типе объекта содержится в' m'; но я не могу сделать 'hlist.head', потому что аргумент' hlist' имеет другой тип; и он выдает ошибку (при создании 'hlist.head'):' не удалось найти неявное значение для параметра c: shapeless.IsHCons [L] ' – DaunnC

+0

@DaunnC: Не' TypeTag'. Вы должны использовать 'Mapper' для' map', 'Reverse' для' reverse' и так далее. – senia

+0

w0w thx! Я попробую; У вас есть некоторые ссылки для меня, чтобы учиться? – DaunnC