Typical duck typing in F #?

using let inline and member restrictions, I can do duck printing for famous members, but what if I wanted to define such a generic function:

let duckwrapper <'a> duck = ...

with the signature 'b β†’' a and where the return value will be the object that implemented 'a (which would be an interface) and redirected calls to the duck.

I did this in C # using Reflection.Emit, but I'm wondering if F # will make reflection, quotes, or other constructs easier.

Any suggestions on how to do this?

EDIT after reading Tim’s answer I thought I would give a little more information

What I thought about when I wrote about using quotes for help was something like this:

{new IInterface with member x.SayHello() = !!<@ %expr @>}

!! which is an operator that translates a quote into a function, and% expr is the unit of work for the method. I could translate the expression into a function (I think), but didn't know how

Of course, this would not do the trick completely, since IInterface would be "a, where I hope that the F # reflection can have some convenient functions so that I can build the type based on the type object and some function values

EDIT How to update Tomas Petricek answer, I will give some code to explain my needs.

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. , , , . . -, reduceBalance, -, boostBalance. let inline . , . ( )

type sourceContract = 
   abstract decreaseBalance : decimal -> sourceContract

. sourceContract, .

+3
2

F #, F # PowerPack. , . , , , . :

#r "FSharp.PowerPack.Linq.dll"
open Microsoft.FSharp.Quotations
open Microsoft.FSharp.Linq.QuotationEvaluation

// Create a part using "Expr." calls explicitly
let expr = Expr.Value(13)
// Create a part using quotation syntax 
let expr2 = <@ (fun x -> x * %%expr) @>

// Compile & Run
let f = expr2.Compile()()
f 10

Expr, . ( ), , F # - ( ).

, , , , , .

+2

F # reflection (Microsoft.FSharp.Reflection) - F # API System.Reflection, , - .

: ( , )

> <@ { new IInterface with member x.SayHello = "hello" } @>;;

  <@ { new IInterface with member x.SayHello = "hello" } @>;;
  ---^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

stdin(7,4): error FS0449: Quotations cannot contain object expressions
> <@ type Test() = class end @>;;

  <@ type Test() = class end @>;;
  ---^^^^

stdin(8,4): error FS0010: Unexpected keyword 'type' in quotation literal

Reflection.Emit - .

Edit:

, F # ,

, . F #: http://msdn.microsoft.com/en-gb/library/ee353491.aspx

+4

Source: https://habr.com/ru/post/1780220/


All Articles