我尝试了以下方法:
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/