我有以下代码:为什么在F#模式匹配中某些表达式中的泛型类型与obj相匹配?
type Message<'a> = | Message of 'a
let handleMessage message =
match box message with
| :? Message<_> -> printfn "Message"
| _ -> printfn "Not message"
let handleMessageEx message =
match box message with
| :? Message<int> -> printfn "Message"
| _ -> printfn "Not message"
handleMessage <| Message 1
handleMessage <| Message (1 :> obj)
handleMessageEx <| Message 1
在F#交互式输出如下:
Not message
Message
Message
为什么第一条语句结果“没有消息”?即当匹配装箱值F#无法检测到它是通用类型消息< _>并且除非我指定底层类型,否则它将其设置为对象(因此在(消息1)上失败匹配)。
不能很好地解释,所以只是一个评论,但泛型类型不是一个真正的类型,所以不能成为模式类型测试的目标。类型测试需要一个“具体”类型,所以通配符被可能的'obj'最普通的东西代替。你可以使函数本身也是通用的'handleMessage <'a>'',但是你需要把通用参数放在调用站点以使它工作'handleMessage<|消息1'(没有你也会得到“Not message”) –
Sehnsucht
问题是obj并不是F#世界中最普通的东西,因为它不会匹配具体的类型。我想知道为什么在消息<'a>的情况下F#不会离开'开放,可用于任何匹配。 –