f# - 如何定义和使用具有不可推断类型参数的事件模式?

标签 f#

我尝试了以下方法:

let inline (|OpAdd|_|) (aty:Type, x:obj, y:obj) =
    if aty.Equals(typeof<'a>) then Some(box ((unbox<'a> x) + (unbox<'a> y)))
    else None

//FSI given signature: 
//val inline ( |OpAdd|_| ) : Type * obj * obj -> obj option

它没有给出警告或错误,但我无法弄清楚如何在调用站点传递显式类型参数,而且似乎 'a 总是被推断为 int.

当我尝试在定义中放置显式参数时,我收到了一些警告和错误:

let inline (|OpAdd|_|)<'a> (aty:Type, x:obj, y:obj) =
    if aty.Equals(typeof<'a>) then Some(box ((unbox<'a> x) + (unbox<'a> y)))
    else None

warning FS1189: Type parameters must be placed directly adjacent to the type name, e.g.       "type C<'T>", not     type "C   <'T>"

error FS0001: The declared type parameter 'a' cannot be used here since the type parameter cannot be resolved at compile time

事件模式是否可以具有明确的类型参数?如果是这样,我该如何定义和使用它们?

最佳答案

我不确定是否有一种干净的方法来执行此操作(可能没有,但我可能是错的)。

作为肮脏的解决方法,您可以添加类型为 'T 的虚拟参数(当使用具有易于创建值的原始类型时)或类型 Expr<'T> (当您真的不想创建实例时)。然后你可以使用带有一些指定类型的虚拟参数的模式:

let inline (|OpAdd|_|) (e:Expr<'T>) (aty:Type, x:obj, y:obj) =
    if aty.Equals(typeof<'T>) then Some(box ((unbox<'T> x) + (unbox<'T> y)))
    else None

let dummy<'T> : 'T = failwith "!"

match (typeof<float>, box 1.1, box 2.1) with 
| OpAdd <@ dummy<int> @> res -> res
| OpAdd <@ dummy<float> @> res -> res
| _ -> null

关于f# - 如何定义和使用具有不可推断类型参数的事件模式?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6636154/

相关文章:

.NET 微型上的 F#

f# - 无法让绑定(bind)运算符与可区分联合一起使用

f# 将二维数组展平为一维数组

.net - 在 F# 中。是否可以重载抽象类型的构造函数?

scala - 为什么棱镜设置函数不返回选项/也许

function - F# 将 Seq 的每个元素分别 append 到另一个元素,然后对每个元素应用一个函数

f# - 尝试将对象转换为泛型类型结果出现 FS0013 错误

.net - 在 F# Interactive 中创建新的 AppDomain

f# - 无法在 C# 项目中引用 'FSharpOption<>'

f# - 如何在 F# 中同时等待取消标记和 EventWaitHandle?