При нормальных обстоятельствах функции F# можно преобразовать в делегаты, вызвав new DelegateType
и передав функцию в качестве аргумента. Но когда делегат содержит параметр byref
, это невозможно напрямую. Например, код:
type ActionByRef<'a> = delegate of 'a byref -> unit
let f (x:double byref) =
x <- 6.0
let x = ref 42.0
let d = new ActionByRef<_>(f)
не будет компилироваться, выдавая следующую ошибку:
Это значение функции используется для построения типа делегата, сигнатура которого включает аргумент byref. Вы должны использовать явное лямбда-выражение, принимающее 1 аргумент.
После появления ошибки, модификация кода для использования
let d = new ActionByRef<_>(fun x -> f(&x))
работает. Но мой вопрос в том, почему это необходимо? Почему F# не разрешает преобразование из именованной функции в делегат, а преобразование из лямбды проходит нормально?
Я столкнулся с таким поведением при исследовании другого вопроса. Я понимаю, что byref
предназначен только для совместимости с другими языками .Net.