General Category > Общий раздел

[ocaml] Найдите ошибку в функции

(1/2) > >>

valexey_u:
Продолжаем нашу рубрику неочевидных ошибок в программах на разных ЯП. На этот раз у нас будет строго статически типизированный функциональный язык - Ocaml.

Итак, вот функция, которая успешно компилируется, запускается, но выдает неверный результат (должна искать индекс минимального элемента массива):


--- Код: ---let min_index a =
  let min i m =
    let m = if a.(i) < a.(m) then i else m in
    if (Array.length a) = (i+1) then
      m
    else
      min (i+1) m
  in
  min 0 0

--- Конец кода ---

Надо найти ошибку и ее исправить.

Geniepro:
А если так:

--- Код: ---let min_index a =
  let min i m =
    let m2 = if a.(i) < a.(m) then i else m in
    if (Array.length a) = (i+1) then
      m2
    else
      min (i+1) m2
  in
  min 0 0
--- Конец кода ---

valexey_u:

--- Цитата: Geniepro от Ноябрь 01, 2016, 04:33:26 am ---А если так:

--- Код: ---let min_index a =
  let min i m =
    let m2 = if a.(i) < a.(m) then i else m in
    if (Array.length a) = (i+1) then
      m2
    else
      min (i+1) m2
  in
  min 0 0
--- Конец кода ---

--- Конец цитаты ---

Неа.

Kemet:
Видимо, так как у функции min отсутствет указание рекурсивности rec, то при вызове min внутри min приведет к вызову предопределенной функции min

valexey_u:

--- Цитата: Kemet от Ноябрь 01, 2016, 06:00:28 pm ---Видимо, так как у функции min отсутствет указание рекурсивности rec, то при вызове min внутри min приведет к вызову предопределенной функции min

--- Конец цитаты ---

Да. Верно. указание рекурсивности rec приводит к изменению области видимости идентификатора данной функции. По умолчанию (без rec) идентификатор функции внутри самой функции не виден, поэтому рекурсивный вызов не возможен.

Подобные приколы также могут произойти не только с предопределенными функциями (входящими в автоимпортируемый модуль Pervasives (  https://caml.inria.fr/pub/docs/manual-ocaml/libref/Pervasives.html ) но и с функциями из других библиотечных модулей если их "импортируешь" через open. В окамле по умолчанию доступны все модули без импортов, просто к сущностям модулей нужно обращаться явно квалифицировав имя модуля. Использовав же open Modulename мы помещаем все сущности модуля Modulename в наш неймспейс (также как предопределенные функции и типы). Со всеми вытекающими.

Поэтому open используют редко. Ну а чтобы узнать какие именно модули использует данный модуль, можно воспользоваться соответствующей стандартной утилитой. Блока импортов там нет.

Навигация

[0] Главная страница сообщений

[#] Следующая страница

Перейти к полной версии