Определение типа данных кортежа неизвестной длины в 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>");

Это статически более безопасный способ.

Другие вопросы по тегам