F#中计量单位的模式匹配 [英] Pattern Matching of Units of Measure in F#

查看:115
本文介绍了F#中计量单位的模式匹配的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

此功能:

let convert (v: float<_>) =
  match v with
  | :? float<m> -> v / 0.1<m>
  | :? float<m/s> -> v / 0.2<m/s>
  | _ -> failwith "unknown"

产生错误

类型'float<'u>'没有任何适当的子类型,因此不能用作类型测试或运行时强制的源.

The type 'float<'u>' does not have any proper subtypes and cannot be used as the source of a type test or runtime coercion.

有什么方法可以图案化匹配的计量单位吗?

Is there any way how to pattern match units of measure?

推荐答案

正如 @kvb 详细解释的那样,问题在于度量单位是该类型的一部分.这意味着float<m>float<m/s>的类型不同(不幸的是,此信息在运行时未存储为值的一部分).

As @kvb explains in detail, the problem is that units of measure are a part of the type. This means that float<m> is different type than float<m/s> (and unfortunately, this information isn't stored as part of the value at runtime).

因此,您实际上是在尝试编写一个可用于两种不同类型输入的函数.干净的功能解决方案是声明一个可以包含第一种类型或第二种类型的值的有区别的联合:

So, you're actually trying to write a function that would work with two different types of input. The clean functional solution is to declare a discriminated union that can hold values of either the first type or the second type:

type SomeValue = 
  | M of float<m>
  | MPS of float<m/s>

然后,您可以使用普通模式匹配来编写函数:

Then you can write the function using ordinary pattern matching:

let convert v = 
  match v with 
  | M v -> v / 0.1<m>
  | MPS v -> v / 0.2<m/s>

您需要将这些值显式包装到已区分的并集值中,但这可能是直接执行此操作的唯一方法(无需在程序结构中进行较大更改).

You'll need to explicitly wrap the values into the discriminated union value, but it's probably the only way to do this directly (without making some larger changes in the program structure).

对于像intfloat这样的普通类型,您也可以使用重载成员(在某些F#类型中声明),但这不适用于度量单位,因为签名在F#之后将是相同的编译器将擦除单元信息.

For normal types like int and float, you could also use overloaded members (declared in some F# type), but that doesn't work for units of measure, because the signature will be the same after the F# compiler erases the unit information.

这篇关于F#中计量单位的模式匹配的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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