Определение типа данных кортежа неизвестной длины в Rascal
Мне было любопытно узнать, можно ли определить тип данных, который мы знаем, должен быть кортежем, но чья длина (или количество элементов неопределяема) в настоящее время. Приложение выглядит следующим образом:
//I want to declare a data type, one of whose argument is a tuple,
public data MyType=fromListCartesianProduct(tuple<?> product)
//Later I want to instantiate a MyType data by using taking List-CartesianProduct
//instantiate some MyType data
foreach(aTuple in [1,2,3]*["a","b"])
someArr[i]=fromListCartesianProduct(aTuple)
Существенное наблюдение состоит в том, что количество элементов в aTuple является неопределимым при объявлении "MyType". Могу ли я объявить такой тип в негодяйском сценарии?
В качестве альтернативы я бы объявил MyType как:
public data MyType=fromListCartesianProduct(list[] product)
и преобразовать каждый кортеж из декартового произведения в список перед построением конкретных экземпляров. Для ясности и других целей я бы хотел определить MyType, как я это делал ранее.
1 ответ
В принципе, ответ - нет. Кортежи имеют фиксированную длину, и у нас (пока) нет полиморфизма строк.
Сказав это, конструкторы данных поддерживают различные виды полиморфизма, которые могут помочь:
полиморфизм строк с использованием параметров ключевых слов, вы всегда можете добавить дополнительные параметры ключевых слов в тип данных, как в
data MyType = myCons(int j = 0); // initial decl data MyType(int k = 1); // extension with another field
перегрузка, вы всегда можете добавить больше конструкторов с большим количеством параметров
data MyType = f(int i); // initial declaration data MyType = f(int i, int j); // overloaded declaration with more fields
Вы можете использовать make
функция от Type
динамически создавать такие конструкторы на основе списков аргументов. На риск времени исполнения исключения типа конечно.
Другой способ работы с данными непредсказуемого типа - перейти на один уровень вверх в иерархии типов (пусть это будет value
), и более поздний шаблон снова будет соответствовать вашему выходу:
list[value] myListRelationOfUnknownType = ...;
for (<int i, int j> <- myListRelationOfUnknownType)
println("printing only pairs of ints: <i> - <j>");
for (<int i, int j, int k> <- myListRelationOfUnknownType)
println("printing only the triples of ints: <i> - <j> - <k>");
Это статически более безопасный способ.