2013-10-13 6 views
3

Таким образом, проблема заключается в понимании HLists бесформенной библиотеки https://github.com/milessabin/shapeless; Я использую HLists для хранения некоторых функций, то есть:Неоднородные списки в Scala; используя функцию карты

val list = HList(
    function1(_), 
    function2(_), 
    .... 
    functionn(_) 
); 

И это отлично работает: я могу взять любую функцию из списка и применить его: list.head(object)

Но я проблема его применения с map функция (list map mapFunc):

object mapFunc extends Poly1 { 
    implicit def default[T] = 
    at[T](t => { 
     t(obj) 
    }) 
} 

Это говорит Application doesnt take parameters. Так как я могу с этим справиться? Мб, я не понимаю, что? Я новичок в Scala.

p.s. есть интересный эффект с конструктором, этот код строит неверный lil бит:

function1(_) :: function2(_) :: HNil признан функцией какого-либо типа, но HList(function1(_), function2(_)) имеет нужный тип.

EDIT

'постскриптум' было принято решение - function1(_) :: function2(_) :: HNil действительно имеет несоответствие типа; но function1 _ :: function2 _ :: HNil в порядке!

ответ

4

Прежде всего, для вашего последнего вопроса - вам необходимо сделать список с HNil, а не HList. Так что, если, например, мы имеем следующее:

def function1(s: String) = "foo " + s 
def function2(s: String) = s.toInt 
def function3(s: String) = s + " bar" 

Мы бы написать:

val list = function1 _ :: function2 _ :: function3 _ :: HNil 

Поскольку :: подобен оператору минусы, которые вы найдете в стандартной библиотеке Scala (и другие языки) в котором он принимает свой первый аргумент (элемент) и добавляет его ко второму (список).

Теперь для вашего первого вопроса. Учитывая HList я только что определили, мы могли бы написать следующее:

val obj = "13" 

object mapFunc extends Poly1 { 
    implicit def funcTo[T] = at[String => T](f => f(obj)) 
} 

И потом:

scala> (list map mapFunc) == "foo 13" :: 13 :: "13 bar" :: HNil 
res0: Boolean = true 

Ключ в том, что вам нужно, чтобы отразить тот факт, что применяется в случае, когда элемент карты является функция из строки (или любого типа вашего объекта) к чему-либо.

+0

oh sry, действительно 'HNil', я ошибся при написании вопроса, исправлен, thx! – DaunnC

+0

Хм, да, я вижу, это действительно интересно; и если я хочу иметь много разных функций, от разных типов до какого-то другого типа? как ~ 'def function1 (s: Type1) = convertType1ToType2' ...' def functionn (s: Typen-1) = convertTypen-1ToTypen'; Я имею в виду smth like 'at [FromType => ToType]'; mb есть способ не писать все случаи для применения неявной функции? – DaunnC

+1

@DaunnC, если вы хотите применить HList функций к HList аргументов, тогда вы должны исследовать zipApply ... но это другой вопрос. –