2015-10-23 8 views
2

Одним из способов реализации «раннее возвращение» в OCaml это с помощью исключений:Можно ли определить исключение внутри функции

exception Exit 

let myfunc() = 
    try 
     for i = 0 to .... do 
     if .. then raise Exit 
     done; false 
    with Exit -> true 

Однако, есть способ, чтобы объявить это Exit исключения в теле функция, поэтому его имя не видимо для других функций в модуле?

(* I would like to do this, but it gives a syntax error *) 
let myfunc() = 
    exception Exit 
    try 
     for i = 0 to .... do 
     if .. then raise Exit 
     done; false 
    with Exit -> true 
+0

Это запах кода. –

+0

Почему вы так думаете? Я думаю, что он более структурирован, чем писать хвостовой рекурсивный цикл. – hugomg

+0

Опираясь на исключения, чтобы вести бизнес-логику, обычно нелепо для меня, хотя я не знаю, для чего вы используете исключение, возможно, это законно, как фатальный для всей программы. –

ответ

3

Да, что вы хотите, можно с помощью локального модуля:

let myfunc() = 
    let module M = struct exception Exit end in 
    try 
    for i = 0 to 3 do 
     if true then raise M.Exit 
    done; false 
    with M.Exit -> true 

Этот стиль не особенно приятно читать, хотя, так что я бы не рекомендовал его. Достаточно опустить показ Exit на следующем интерфейсе модуля, если вы хотите скрыть его от большей части остальной части программы.

+2

Обратите внимание, что если вы не хотите отлаживать это исключение, возможно, из-за использования его для потока управления, вы, вероятно, должны использовать 'raise_notrace' вместо' raise': http://caml.inria.fr/pub/docs/ manual-ocaml/libref/Pervasives.html # VALraise_notrace – antron

+0

@antron Я согласен с вами в том смысле, что намерение заключается в том, чтобы использовать исключение очень локально, а также что оно является частью нормального потока управления программой и должно быть недорогим для повышения. И в то же время OP не говорит, что они не ожидают отладки исключения. Они говорят, что они не хотят, чтобы у исключения было имя за пределами 'myfunc' (или содержащего модуль, если они следуют моей рекомендации), что, если угодно, облегчает, а не сложнее, недостаточно для того, чтобы быть пойманным :) –

+0

Достаточно честный - я имел в виду условную рекомендацию для ОП, как это в моем комментарии. Я не хотел предлагать вам отредактировать свой ответ, за исключением, возможно, включения комментария в качестве последней дополнительной заметки, в лучшем случае. Поэтому я думаю, что комментарий достаточно :) – antron

Смежные вопросы