Дополнительные параметры и типы опций с использованием F #
Рассмотрим следующий код:
type Test () =
member o.fn1 (?bo) = 1
member o.fn2 (?bo) = o.fn1 bo
member o.fn3 (?bo) = 1 + bo.Value
member o.fn4 (?bo) = o.fn3 bo
Пока fn1
и fn2
работают нормально, fn4
выдает следующую ошибку:
init.fsx(6,30): ошибка FS0001: ожидается, что это выражение будет иметь тип int, но здесь есть тип 'a option
MSDN:
Необязательные параметры интерпретируются как тип опции F #, поэтому вы можете запросить их обычным образом, чтобы типы опций были запрошены, используя выражение соответствия с Some и None.
Для меня необязательные параметры не интерпретируются как тип опции F #, иначе код будет скомпилирован. Более того, я не понимаю, почему, когда я нависаю над ?bo
в fn3
, всплывающая подсказка говорит val bo: int option
, но извне ожидает только int
. Я ожидал бы поведения, не принимающего ничего, int, Some int и None. И как последнее примечание, я не понимаю, почему fn2
работает, но fn4
не делает.
Спасибо за разъяснение
Ответы
Ответ 1
Я должен пересмотреть правильный ответ. На основании этого вопроса (и ответа):
Распространение необязательных аргументов
это означает, что правильный ответ таков:
type Test () =
member o.fn1 (?bo) = 1
member o.fn2 (?bo) = o.fn1 bo
member o.fn3 (?bo) = 1 + bo.Value
member o.fn4 (?bo) = o.fn3 (?bo = bo)
Это аккуратная функция и кредиты для ответа перейдите на desco!
Ответ 2
-
fn2
работает, потому что fn1
не использует свой параметр, который, таким образом, является общим 'b option
.
type Test () =
member o.fn1 (?bo1) = 1 --> bo1: 'b option, here 'b = 'a option
member o.fn2 (?bo) = o.fn1 bo -->bo: 'a option
-
fn4
жалуется, что параметр, переданный в fn3
, должен быть int, но не int option
, потому что когда вы укажете параметр, вам, конечно, необходимо передать конкретный. Но у вас есть возможность опустить параметр. Сигнатура определения/типа fn3
не знает, указали ли вы bo
или нет, поэтому это int option
. Обратите внимание, что вы можете использовать следующее:
type Test () =
member o.fn1 (?bo) = 1
member o.fn2 (?bo) = o.fn1 bo
member o.fn3 (?bo) =
match bo with
| Some v -> 1 + bo.Value
| None -> 1
member o.fn4 (?bo) = o.fn3()
где вы не укажете параметр для fn3
, но когда вы укажете его, это конкретный int
, а не int option
.
Подумайте о функции построения графика с тремя параметрами:
let plot(?x,?y,?color)
поскольку параметры являются необязательными, вы можете использовать следующее:
plot(data)
plot(y=data)
plot(x=data, color='r')
Но не:
plot(Some data)
plot(y=Some data)
plot(x=Some data, color=Some 'r')