gpt4 book ai didi

generics - F# 泛型和转换

转载 作者:行者123 更新时间:2023-12-01 23:25:43 25 4
gpt4 key购买 nike

在阅读了所有建议的相关问题后,我找不到问题的答案。写信给您,希望您能尽快答复,并宽容地判断我在这方面的知识不足。

我有一个类型来体现函数定义:

type FunctionDefinition<'a>(exec:int->(Data.Reader->'a)) =
member x.Exec = exec
member x.ReturnType = typeof<'a>

如您所见,exec应该是一个接受一个 int 的函数参数并返回另一个接受一个 Data.Reader 的函数参数并返回 'a 类型的值(这样一个令人筋疲力尽的短语!)。 Data.Reader的定义在这里无关紧要。

此外,我还有一本字典要保留string->FunctionDefinition对如下:

let FUNCTIONS = new Generic.Dictionary<string, FunctionDefinition<obj>>()

FunctionDefinition FUNCTIONS 中的实例将拥有多种类型的功能,这就是为什么它是 FunctionDefinition<obj> (我相信这是罪恶的根源,但我无法避免这一点,所以我来了)。

然后我有一些函数要包装在 FunctionDefinition 中并放入 FUNCTIONS :

/// Function definitions
let unchanged (id:int) =
let mutable last = null
fun (reader:Data.Reader) ->
if last = null then
false
else
let cur = reader.GetValue(id)
let ret = last.Equals(cur)
last <- cur
ret

let changed (id:int) =
let un = unchanged id
fun(reader:Data.Reader) ->
not (un reader)

let dummyfortesting (id:int) =
fun(x) -> "yam-yam"

我以为我可以将这些功能添加到我的字典中,但是......没有那种东西!以下代码:

FUNCTIONS.Add("unchanged", new FunctionDefinition<bool>(unchanged))
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
FUNCTIONS.Add("changed", new FunctionDefinition<bool>(changed))
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
FUNCTIONS.Add("dummy", new FunctionDefinition<string>(dummyfortesting))
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

给出明确的错误信息:

// The type 'obj' does not match the type 'bool'
// The type 'obj' does not match the type 'bool'
// The type 'obj' does not match the type 'string'

而以下是正确的:

typeof<bool>.isSubclassOf(typeof<obj>) // -> true

这不公平,不是吗?


问题是

如何实例化FUNCTIONS容纳多个的字典FunctionDefinition<bool> , FunctionDefinition<string>实例?

或者除了保留通用 FunctionDefinition 之外还有其他解决方案吗?返回不同类型的函数的类型?


一种解决方案是将所需类型作为参数传递给 FunctionDefinition 的构造函数如下:

type FunctionDefinition(typ:System.Type, exec:int->(Data.Reader->???)) =
member x.Exec = exec
member x.ReturnType = typ

但是这里不清楚如何声明exec .

希望我说得足够清楚。

非常感谢。

此致

Kh

最佳答案

您正在创建的字典需要保存相同类型的值。如果你创建两个 FunctionDefinition<'T>具有不同类型参数的值,它们将是不同的类型,因此它们不能组合在一个字典中。

解决这个问题的一种方法是定义一个非泛型接口(interface)并创建一个字典来存储这个接口(interface)的值(这将由所有泛型 FunctionDefinition<'T> 对象实现)

type IFunctionDefinition =
abstract ReturnType : System.Type
abstract Exec : int -> (Reader -> obj)

let dict = new Dictionary<string, IFunctionDefinition>()

Exec函数必须返回 obj ,因为在将函数存储在(同类)字典中后无法恢复类型信息。然后您的具体类型可以实现接口(interface):

type FunctionDefinition<'a>(exec:int->(Reader->'a)) = 
member x.Exec = exec
interface IFunctionDefinition with
member x.ReturnType = typeof<'a>
member x.Exec n = fun rdr -> box (exec n rdr)

现在您可以将创建的函数定义添加到字典中,因为它们实现了通用接口(interface):

let foo = FunctionDefinition<int>(fun _ _ -> 42)
dict.Add("foo", foo)

另一种方法 是使类型定义非泛型。在使用字典中的函数以确定它们返回的值时,您需要进行一些动态类型测试。您可以通过使用可区分的联合作为返回类型来明确这一点:

type ResultType =
| String of string
| Bool of bool
// etc. for all supported return types

关于generics - F# 泛型和转换,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5567327/

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