В Scala возможно следующее:
scala> val l = List
l: scala.collection.immutable.List.type = scala.collection.immutable.List$@7960c21a
scala> l ( 1, 2, 3 )
res0: List[Int] = List(1, 2, 3)
Другими словами, Scala имеет полиморфизм более высокого порядка. Я хотел бы использовать полиморфизм более высокого порядка, чтобы сделать следующее.
sealed abstract class A { def eval () : A }
case class A0 () extends A { ... }
case class A1 ( a : A ) extends A { ... }
case class A2 ( a : A, b : A ) extends A { ... }
....
Итак, у меня есть несколько классов case, подклассов A
, конструкторы которых не обязательно принимают одинаковое количество аргументов.Я также хотел бы иметь «общий» класс case, примерно такой:
case class ApplyA ( c : ???, l : List [ A ] ) extends A {
def eval () : A = { ??? } }
Идея состоит в том, что ApplyA
принимает в качестве первого аргумента конструктор для чего-то, что является подтипом A
и список аргументов. Затем метод eval
создает соответствующий класс с конструктором, если это возможно (т. Е. Список имеет правильную длину) и возвращает его
(это соответствует l (1, 2, 3 )
в примере List
выше). Каким будет тип аргумента первого конструктора для ApplyA
?
Это должно быть возможно с полиморфизмом более высокого порядка, но я не мог понять, как это сделать. Я знаю, что могу сделать это даже без использования полиморфизма более высокого порядка, просто заключив конструкторы в функции, а затем передав эти функции в качестве первого аргумента конструктору для ApplyA
, но я хотел бы понять, как использовать полиморфизм высшего порядка напрямую.