, используя let inline и ограничения членов, я буду в состоянии вводить утку для известных членов, но что, если я хотел бы определить обобщенную функцию следующим образом:
let duckwrapper <'a> duck = ...
с подписью 'b ->' a и где возвращаемое значение будет объектом, который реализует 'a (который будет интерфейсом) и перенаправляет вызовы к утке.
Я сделал это в C #, используя Reflection.Emit, но мне интересно, упростит ли это отражение, цитаты или другие конструкции F #.
Есть предложения о том, как этого добиться?
EDIT
Прочитав ответ Тимса, я подумал, что дам немного больше подробностей
То, о чем я думал, когда писал об использовании цитат, чтобы помочь, было что-то вроде:
{new IInterface with member x.SayHello() = !!<@ %expr @>}
!! будучи оператором, переводящим предложение в функцию, а% expr является единицей работы для метода. Я мог бы перевести выражение в функцию (я думаю), но не знал бы, как
конечно, это тоже не сработало бы полностью, так как IInterface был бы 'a, и я надеюсь, что в отражении F # могут быть некоторые удобные функции, чтобы я мог создать тип на основе объекта типа и значений некоторых функций
EDIT
В качестве обновления к ответу Томаса Петричека я дам код, объясняющий мои потребности
type SourceRole =
abstract transfer : decimal -> context
and context(sourceAccount:account, destinationAccount) =
let source = sourceAccount
let destination = destinationAccount
member self.transfer amount =
let sourcePlayer =
{new SourceRole with
member this.transfer amount =
use scope = new TransactionScope()
let source = source.decreaseBalance amount
let destination = destination.increaseBalance amount
scope.Complete()
context(source,destination)
}
sourcePlayer.transfer(amount)
, который является попыткой перенести "учебник" из примера DCI в F #. Источником и назначением являются роли DCI. Это идея, что любой объект данных, который придерживается определенного контракта, может их воспроизвести. В этом случае договор прост. Для источника нужна функция-член, называемая lowerBalance, а для назначения требуется функция-член, называемая увеличения.
Я могу сделать это для этого конкретного случая с помощью inline и членства let.
Но я хотел бы написать набор функций, которые предоставляют интерфейс и объект. В этом случае это может быть источник (как объект) и
type sourceContract =
abstract decreaseBalance : decimal -> sourceContract
как тип. Результатом будет объект типа sourceContract, который будет передавать вызовы метода методу с тем же именем в исходном объекте.