F# try-with в сочетании с reraise() возвращает допустимый тип. Зачем?

Я пытаюсь выяснить пример с F#. И, как я понял, тип возвращаемого значения try должен совпадать с типом возвращаемого значения with.

Но почему тогда, когда я делаю что-то вроде этого:

 let safeIndexTry (anArray : array<'a>) (i : int) = 
  try 
    Array. item i anArray
  with
    | :? System.IndexOutOfRangeException as ex -> printfn "%s" ex.Message 
                                                  reraise()

тогда, как я могу понять это. затем reraise() превращает возвращаемое значение в допустимый тип. в этом случае Int. Но почему это? и это для всех типов ререйз будет делать это?

В общем, я нахожу немного проблематичным, что оба должны иметь одинаковый тип возвращаемого значения. Я имею в виду, что обычно вы хотите вычислить какое-то значение и, если оно не может поймать исключение, выдает строковое сообщение. Кто-нибудь может дать мне какое-нибудь руководство?

1 ответ

Решение

reraise определяется так:

reraise : unit -> 'T

Это означает, что его тип результата соответствует типу охватывающей функции, из которой он возвращается. Его возвращаемое значение более или менее бессмысленно из-за создаваемого исключения. В таких языках, как Haskell, это можно считать дном.

Поскольку функция должна иметь тот же тип результата, более идиоматическим значением, которое нужно вернуть, будет Option тип. Затем вы можете вернуться None если исключение поймано, и Some goodValue когда операция прошла успешно. Эта идиома гораздо предпочтительнее использования исключений для обработки потока управления, потому что все вызывающие должны явно обрабатывать оба None а также Some случаев, вместо того, чтобы обернуть весь вызывающий код с обертками обработки исключений.

Вот как бы выглядела ваша функция при конвертации в использование Option:

let safeIndexTry (anArray : array<'a>) (i : int) : 'a option = 
  try 
    Some <| Array. item i anArray
  with
    | :? System.IndexOutOfRangeException as ex -> None
Другие вопросы по тегам