gpt4 book ai didi

reflection - 在 F# 中输入通用鸭子类型(duck typing)?

转载 作者:行者123 更新时间:2023-12-01 11:07:02 27 4
gpt4 key购买 nike

使用 let inline 和成员约束,我将能够为已知成员进行 duck typing,但是如果我想像这样定义一个通用函数怎么办:

let duckwrapper<'a> duck = ...

带有签名 'b -> 'a 并且返回值将是一个对象,该对象实现了 'a(这将是一个接口(interface))并将调用转发给 duck。

我在 C# 中使用 Reflection.Emit 完成了此操作,但我想知道 F# 反射、引号或其他构造是否会使它更容易。

关于如何实现这一点有什么建议吗?

编辑阅读蒂姆斯的回答后,我想我会提供更多细节

当我写关于使用引用来帮助的文章时,我在想的是这样的:

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

!!作为将引语翻译成函数的运算符,%expr 是该方法的工作单元。我能够将表达式转换为函数(我猜)但不知道如何

当然这也不能完全解决问题,因为 IInterface 将是“我希望 F# 反射可能有一些方便的函数的地方,这样我就可以基于类型对象和一些函数值构造一个类型”

编辑作为对 Tomas Petricek 回答的更新,我将提供一些代码来解释我的需求

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 的“the”教科书示例在 F# 中。源和目标是 DCI 角色。它的想法是任何遵守特定契约(Contract)的数据对象都可以播放这些内容。在这种情况下,契约(Contract)很简单。 source 需要一个名为 decreaseBalance 的成员函数,destination 需要一个名为 increaseBalance 的成员函数。我可以通过 let inline 和成员约束来完成这个特定案例。但我想编写一组给定接口(interface)和对象的函数。在这种情况下,它可以是源(作为对象)和

type sourceContract = 
abstract decreaseBalance : decimal -> sourceContract

作为类型。结果将是一个 sourceContract 类型的对象,它将方法调用传递给源对象上具有相同名称的方法。

最佳答案

F# 反射 (Microsoft.FSharp.Reflection) 是一个 F# 友好的包装器,围绕着普通的 System.Reflection API,所以我认为它不会添加任何东西在这里。

引用不能定义新类型:(你需要定义一个新类型来进行基于接口(interface)的鸭子类型(duck typing))

> <@ { 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 仍然是解决这个问题的方法。

编辑:

I hope F# reflection might have some handy functions so that I could construct a type based on a type object and some function values

恐怕不行。这是有关 F# 反射的文档:http://msdn.microsoft.com/en-gb/library/ee353491.aspx

关于reflection - 在 F# 中输入通用鸭子类型(duck typing)?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4440109/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com