使用“灵活”与泛型类型进行模式匹配类型参数
match value with
| :? list<#SomeType> as l -> l //Is it possible to match any list of a type derived from SomeType?
| _ -> failwith "doesn't match"
match value with
| :? list<#SomeType> as l -> l //Is it possible to match any list of a type derived from SomeType?
| _ -> failwith "doesn't match"
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(5)
正如已经指出的,没有办法直接做到这一点(模式匹配只能绑定值,但不能绑定新类型变量)。除了 kvb 的(更通用的)解决方法之外,您还可以使用所有集合都实现非泛型
IEnumerable
的事实,因此您可以检查此类型:代码测试该值是否是非泛型
IEnumerable
以及类型参数是否是SomeType
的子类型。在这种情况下,我们得到了一些派生类型的列表,因此我们可以将其转换为SomeType
值的序列(这与使用派生类型的值列表略有不同,但它应该对于实际目的来说并不重要)。As already pointed out, there is no way to do this directly (pattern matching can only bind values, but it cannot bind new type variables). In addition to the (more general) workaround by kvb you can use the fact that all collections implement non-generic
IEnumerable
, so you can check for this type:The code tests whether the value is a non-generic
IEnumerable
and whether the type parameter is subtype ofSomeType
. In that case, we got a list of some derived type, so we can cast it to a sequence ofSomeType
values (this is slightly different than working with list of values of the derived types, but it shouldn't matter for practical purposes).不,不幸的是不可能做这样的事情 - CLR 没有提供任何有效的方法来进行此类类型测试。请参阅如何转换对象F# 中的泛型类型列表 和 F# 和在实现接口的非泛型方法中对泛型进行模式匹配,用于一些(相当丑陋的)解决方案。
No, it's unfortunately not possible to do something like this - the CLR doesn't provide any efficient way of doing that kind of type test. See How to cast an object to a list of generic type in F# and F# and pattern matching on generics in a non-generic method implementing an interface for a few (rather ugly) solutions.
后来我需要类似的东西来匹配惰性实例。这是我的解决方案,以防有人觉得有帮助。
用法:
I later needed something similar for matching Lazy instances. Here's my solution, in case anyone finds it helpful.
Usage:
根据 F# 2.0 规范,帕。 14.5.2(解决子类型约束),它不起作用,因为:“F#泛型类型不支持协变或逆变。”
According to the F# 2.0 specification, par. 14.5.2 (Solving Subtype Constraints), it will not work, because: "F# generic types do not support covariance or contravariance."
不是最干净的,但很有效:
Not the cleanest, but effective: