为什么某些表达式中的泛型类型在 F# 模式匹配中被匹配为 obj? [英] Why is generic type in some expressions is matched as obj in F# pattern matching?

查看:9
本文介绍了为什么某些表达式中的泛型类型在 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# Interactive 的输出如下:

The output in F# Interactive is the following:

Not message
Message 
Message

为什么第一条语句会导致Not message"?IE.当匹配一个装箱值时,F# 无法检测到它是泛型类型 Message<_>,除非我指定了底层类型,否则它将它设置为 object(因此匹配失败(消息 1)).

Why does the first statement result in "Not message"? I.e. when matching a boxed value F# is not able to detect that it is of a generic type Message<_> and unless I specify the underlying type it sets it to object (therefore failing match on (Message 1)).

推荐答案

每当您将 _ 视为类型参数时,请将其视为您不关心的新类型参数.如果我们相应地调整您的第一个定义:

Whenever you see _ as a type parameter, think of it as a fresh type parameter that you don't care about. If we tweak your first definition accordingly:

let handleMessage message =
    match box message with
    | :? Message<'_a> -> printfn "Message"
    | _ -> printfn "Not message"

然后编译器给了我们这个有用的线索:

then the compiler gives us this helpful clue:

警告 FS0064:此构造导致代码不如类型注释所指示的通用.类型变量 '_a 已被约束为类型 'obj'.

warning FS0064: This construct causes code to be less generic than indicated by the type annotations. The type variable '_a has been constrained to be type 'obj'.

问题是类型参数必须被赋予一些特定的值,但是编译器没有选择一个的依据,所以它默认为obj,即不是你想要的.

The problem is that the type parameter has to be given some specific value, but the compiler has no basis on which to pick one so it defaults to obj, which is not what you want.

没有开箱即用的好方法,但您可以创建一个活动模式来稍微简化体验:https://stackoverflow.com/a/2140485/82959.

There's no great way to do this out of the box, but you can create an active pattern to simplify the experience somewhat: https://stackoverflow.com/a/2140485/82959.

这篇关于为什么某些表达式中的泛型类型在 F# 模式匹配中被匹配为 obj?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆