Ошибка аргумента в моем коде цикла "Для" (Оз / Моцарт)

Я недавно начал изучать Oz/Mozart, и для практики я пытаюсь написать код простой процедуры "For", которая переходит от значений "Init" к "End", и в каждом цикле печатает текущий номер цикла в браузере. Вот код:

Эта процедура создает список от значения Init до End:

declare
fun {Listing Init End}
   if Init == End then
      [Init]
   else
      Init|{Listing Init+1 End}
   end
end

Это делает цикл и применяет функцию "F" в каждом цикле:

declare ForList
fun {ForList F L}
   case L of H|T then
      {F H}|{ForList F T}
   else nil end
end

Это оборачивает вышеупомянутые функции, чтобы можно было получать значения Init и End вместо списка:

declare MyFor L X in
proc {MyFor F Init End}
   L = {Listing Init End}
   X = {ForList F L}
end

Наконец, я звоню MyFor:

{MyFor Browse 1 4}

Когда я пытаюсь скомпилировать, я получаю эту ошибку:

%*************** Error: illegal number of arguments *************
%**
%** In statement: {<P/1 Browse> 1 _<optimized>}
%** Expected:     1 argument
%** Found:        2 arguments
%**
%** Call Stack:
%** procedure 'ForList' in file "Oz", line 11, column 0, PC = 15793

(Строка 11 "fun {ForList F L}")

Я пытался поменять местами "func" и "proc" в некоторых подпрограммах, чтобы посмотреть, что-то изменится, но я действительно не знаю, что я делаю неправильно.

1 ответ

Решение

ForList ожидает функцию, которая отображает элементы в результате. Но Browse это процедура, которая ничего не возвращает. ForList должно выглядеть примерно так:

proc {ForList F L}
  case L of H|T then
    {F H}
    {ForList F T}
  else
    skip
  end
end

Это как раз и есть разница между встроенной функцией List.forAll а также List.map,

Кстати, в определении MyFor вы используете глобальные переменные X а также L, Это вызовет проблемы, когда MyFor называется не раз. Вместо этого вы должны использовать локальные переменные. Вот так:

proc {MyFor F Init End}
  L X
in
  L = {Listing Init End}
  X = {ForList F L}
end
Другие вопросы по тегам