WedX - журнал о программировании и компьютерных науках

Как решить, что общие параметры не разрешены

TL;DR: Если у вас возникла похожая проблема, сначала проверьте, не сделали ли вы что-то совершенно глупое, например, перепутали : с =. Я был так сбит с толку сообщением об ошибке, что мне удалось воспроизвести глупую ошибку еще одной глупой ошибкой, так что смейтесь от души:

Я столкнулся с проблемой, когда я боролся с ошибкой no generic parameters allowed. Проблема, вероятно, лучше всего объяснена в упрощенном виде: Проблема сравнения кортежа только по его первому элементу. Рассмотрим этот пример:

import algorithm

# just a dummy type emphasizing that it should not be
# used for the comparison
type
  NotComparable = object

# generic proc to compare a tuple by the first element
proc cmpByKey[K,V](x: (K,V), y: (K,V)): int = 
  system.cmp(x[0], y[0])

# now the actual challenge: how to write a function which
# takes some collection of tuples and defines a local
# key comparator for the given tuple.
proc sortByFirstTupleElement[K,V](data: seq[(K,V)]) =
  let compare = cmpByKey[K,V]
  sort[(K,V)](cmp: compare)

let data = @[(2, NotComparable()),
             (1, NotComparable()),
             (3, NotComparable())]

sortByFirstTupleElement[int, NotComparable](data)

В этом примере создается Error: no generic parameters allowed for sort. Я пробовал все виды синтаксических вариаций, а также определял вложенный процесс компаратора. Что я не понимаю: почему компаратор до сих пор считается универсальным? Я ожидал, что в пределах sortByFirstTupleElement типы K и V будут экземплярами типов из вызывающего контекста, то есть int и NotComparable. Поэтому я ожидал, что cmpByKey[K,V] будет конкретным cmpByKey[int,NotComparable]. Есть ли синтаксический трюк, чтобы сделать компаратор конкретным?

Если это невозможно, каковы возможные обходные пути здесь? Может не только конкретно в этом примере, а вообще? Я предполагаю, что эта проблема возникает каждый раз, когда общий процесс должен передать другой процесс, который включает общий тип?

20.05.2015

Ответы:


1

Ваша проблема в том, что вы вызываете sort с неправильными параметрами. Вы не передаете параметр data для сортировки, а data не является параметром var, поэтому он не может быть изменен. Кроме того, cmp не является именованным параметром, поэтому просто передайте функцию сравнения напрямую. Например.:

import algorithm

# just a dummy type emphasizing that it should not be
# used for the comparison
type
  NotComparable = object

# generic proc to compare a tuple by the first element
proc cmpByKey[K,V](x: (K,V), y: (K,V)): int = 
  system.cmp(x[0], y[0])

# now the actual challenge: how to write a function which
# takes some collection of tuples and defines a local
# key comparator for the given tuple.
proc sortByFirstTupleElement[K,V](data: var seq[(K,V)]) =
  let compare = cmpByKey[K,V]
  data.sort(compare)

var data = @[(2, NotComparable()),
             (1, NotComparable()),
             (3, NotComparable())]

sortByFirstTupleElement(data)

Кроме того, let compare = ... лишнее. Вы можете позвонить data.sort(cmpByKey[K,V]) напрямую.

Вы получаете сообщение об ошибке, потому что вы используете синтаксис конструктора объекта (cmp: compare), а не синтаксис именованного параметра (cmp = compare), что заставляет Nim искать тип объекта с именем sort, а не процедуру с именем sort. Сообщение об ошибке все еще немного сбивает с толку, но это то, откуда оно исходит.

20.05.2015
  • О, какая глупая ошибка... Это сообщение об ошибке заставляло меня все время беспокоиться о чем-то совершенно неправильном. Аналогично в моей исходной задаче. Там проблема была дополнительно запутана следующим удивительным поведением: по какой-то причине, если аргумент компаратора имеет значение по умолчанию system.cmp, моя переданная функция игнорируется (хотя не может воспроизводиться тривиально). Может быть, это причина, по которой sort не имеет значения по умолчанию для cmp в первую очередь? 20.05.2015
  • Я обновил сообщение, чтобы объяснить причину запутанного сообщения об ошибке. 20.05.2015
  • Новые материалы

    Как проанализировать работу вашего классификатора?
    Не всегда просто знать, какие показатели использовать С развитием глубокого обучения все больше и больше людей учатся обучать свой первый классификатор. Но как только вы закончите..

    Работа с цепями Маркова, часть 4 (Машинное обучение)
    Нелинейные цепи Маркова с агрегатором и их приложения (arXiv) Автор : Бар Лайт Аннотация: Изучаются свойства подкласса случайных процессов, называемых дискретными нелинейными цепями Маркова..

    Crazy Laravel Livewire упростил мне создание электронной коммерции (панель администратора и API) [Часть 3]
    Как вы сегодня, ребята? В этой части мы создадим CRUD для данных о продукте. Думаю, в этой части я не буду слишком много делиться теорией, но чаще буду делиться своим кодом. Потому что..

    Использование машинного обучения и Python для классификации 1000 сезонов новичков MLB Hitter
    Чему может научиться машина, глядя на сезоны новичков 1000 игроков MLB? Это то, что исследует это приложение. В этом процессе мы будем использовать неконтролируемое обучение, чтобы..

    Учебные заметки: создание моего первого пакета Node.js
    Это мои обучающие заметки, когда я научился создавать свой самый первый пакет Node.js, распространяемый через npm. Оглавление Глоссарий I. Новый пакет 1.1 советы по инициализации..

    Забудьте о Matplotlib: улучшите визуализацию данных с помощью умопомрачительных функций Seaborn!
    Примечание. Эта запись в блоге предполагает базовое знакомство с Python и концепциями анализа данных. Привет, энтузиасты данных! Добро пожаловать в мой блог, где я расскажу о невероятных..

    ИИ в аэрокосмической отрасли
    Каждый полет – это шаг вперед к великой мечте. Чтобы это происходило в их собственном темпе, необходима команда астронавтов для погони за космосом и команда технического обслуживания..


    Для любых предложений по сайту: [email protected]