2015-04-16 2 views
3

я следующий код:переменное число аргументов для абстрактной функции

trait TypeLike 
trait ArgLike 
trait Predicate{ 
    def name:String 

} 

case class Arg(name:String) 

case class Predicate1[I1<:Arg,O<:TypeLike](name:String, arg1:I1, output:O, func: I1=> O) extends Predicate 


case class Predicate2[I1<:Arg,I2<:Arg,O<:TypeLike](name:String, arg1:I1,arg2:I2, output:O, func: (I1,I2)=> O) 
    extends Predicate 

Как я могу поместить «Func» в Predicate черты. Я не знаю, как определить абстрактную функцию с переменными числами ввода.

ответ

1

К сожалению, для этого вам необходимо использовать HLists. Вот пример с бесформенным HLists:

import shapeless._ 

trait Predicate[Args <: HList, O <: TypeLike] { 
    implicit val lubWitness: LUBConstraint[Args, Arg] 
    def name: String 
    def func: Args => O 
} 

case class Predicate1[I1 <: Arg, O <: TypeLike](
    name: String, 
    arg1: I1, 
    output: O, 
    func: I1 :: HNil => O 
) extends Predicate[I1 :: HNil, O] { 
    implicit val lubWitness = implicitly[LUBConstraint[I1 :: HNil, Arg]] 
} 

case class Predicate2[I1 <: Arg, I2 <: Arg, O <: TypeLike](
    name: String, 
    arg1: I1, 
    arg2: I2, 
    output: O, 
    func: I1 :: I2 :: HNil => O 
) extends Predicate[I1 :: I2 :: HNil, O] { 
    implicit val lubWitness = implicitly[LUBConstraint[I1 :: I2 :: HNil, Arg]] 
} 

// Example instantiation 
val p1 = Predicate1("Example", Arg("test"), new TypeLike {}, 
    (args: Arg :: HNil) => { println(args(0)); ??? }) 

Объяснения

Так что здесь происходит? HList - это в основном кортеж на стереоидах. Давайте посмотрим на примере, мы имеем:

trait Predicate[Args <: HList, O <: TypeLike] { 

Args <: HList означает Args список типов. O <: TypeLike - параметр нормального типа с привязкой.

implicit val lubWitness: LUBConstraint[Args, Arg] 

Это говорит о том, что нам нужно доказательство того, что каждый тип в HList Args подтипом Arg (я предполагаю, что это является requriement.

def func: Args => O 

Функция, которая принимает HList из " форма»Args и возвращает O. (вы также можете написать это как метод, если вы предпочитаете.

case class Predicate1 /*snip*/ extends Preciate[I1 :: HNil, O] 

Predicate1 - это Predicate, список аргументов которого содержит один элемент типа I1.

implicit val lubWitness = implicitly[LUBConstraint[I1 :: HNil, Arg]] 

Получить и определить свидетельство, что I1 подтипом Arg (что имеет место, в связи с типом связанного в декларации Predicate1.

+0

спасибо, это Shaeless 2? – Omid

+0

Должен работать и с более старыми версиями Shapeless. – gzm0

+0

Вы могли бы предоставить экземпляр Predicate1? Я не могу давать аргументы как Hlist – Omid

-2

Кортежи как параметры типа могут имитировать нечто похожее на ваш вопрос. Этот подход имеет 2 ограничения. Вы должны использовать дополнительные парсеры для вызова func, а кортеж имеет ограничение на 22 элемента.

trait TypeLike 
trait ArgLike 
trait Predicate[X, O] { 

    def name:String 

    def func(f: X): O 
} 

case class Arg(name:String) 

case class Predicate1[I1<:Arg,O<:TypeLike, X <: Tuple1[I1]](name:String, arg1:I1, output:O) extends Predicate[X, O] { 
    override def func(f: X): O = ??? 
} 


case class Predicate2[I1<:Arg,I2<:Arg,O<:TypeLike, X <: Tuple2[I1, I2]](name:String, arg1:I1,arg2:I2, output:O) 
    extends Predicate[X, O] { 
    override def func(f: X): O = ??? 
} 
+0

Я хочу его «Func» и типы должны – Omid

+0

func: (I1 *, I2 *) => O – MGolovanov

+0

func: ((I1, I2) => O) * – MGolovanov

Смежные вопросы