在F#3.0中打破活动模式

Dan*_*iel 8 f# active-pattern f#-3.0 visual-studio-2012

这个活动模式使用F#2.0编译:

let (|Value|_|) value = // 'a -> 'T option
  match box value with
  | :? 'T as x -> Some x
  | _ -> None
Run Code Online (Sandbox Code Playgroud)

但是,在F#3.0中,发出错误:

活动模式'|值| _ |' 具有包含不由输入确定的类型变量的结果类型.当没有提到结果案例时,常见原因是[sic],例如'let(| A | B |)(x:int)= A x'.这可以通过类型约束来修复,例如'let(| A | B |)(x:int):Choice = A x'

我试过了:

let (|Value|_|) value : 'T option = ...
Run Code Online (Sandbox Code Playgroud)

和:

let (|Value|_|) (value: 'U) = ...
Run Code Online (Sandbox Code Playgroud)

怎么修好?

环境:Visual Studio 2012(RTM)和FSI v11.0.50727.1

编辑:这是一个更简单的repro:

let (|X|) x = unbox x
Run Code Online (Sandbox Code Playgroud)

Bri*_*ian 4

F# 2.0 编译器中存在一个错误,编译器对结果中具有自由类型变量的某些活动模式进行了不正确的分析和错误的代码生成;一个简单的重现是

let (|Check|) (a : int) = a, None
//let (|Check|) (a : int) = a, (None : int option)

let check a = 
    match a with
    | Check (10, None) -> System.Console.WriteLine "10"
    | Check (20, None) -> System.Console.WriteLine "20"

check 10
check 20
Run Code Online (Sandbox Code Playgroud)

它在编译时生成一个奇怪的警告并编译成看似不正确的代码。我猜测我们在 F# 3.0 中修复此错误(并限制一些疯狂情况)的尝试也破坏了一些法律代码,作为修复的附带损害。

我将提交另一个错误,但对于 F# 3.0,听起来您需要使用其他答案中提到的解决方法之一。