General Category > Общий раздел
[ocaml] Найдите ошибку в функции
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 используют редко. Ну а чтобы узнать какие именно модули использует данный модуль, можно воспользоваться соответствующей стандартной утилитой. Блока импортов там нет.
Навигация
Перейти к полной версии