使用F#Active Pattern混淆错误

时间:2010-10-01 21:58:20

标签: f#

为什么要编译:

let (|T|F|) b = 
    let f (o:int) : obj = null
    if b then T else F(f)

虽然失败了:

let (|T|F|) b = 
    let f (o:obj) : obj = null
    if b then T else F(f)

两个例子之间的区别是参数'o'被强制为'int'(编译)或'obj'(编译失败)

1 个答案:

答案 0 :(得分:8)

这是一个不幸的类型推理角落案例。这将有效:

let (|T|F|) b : Choice<unit,obj -> obj> =   
  let f (o:obj) : obj = null
  if b then T else F(f)

在原始代码中,尽管您的注释为(o:obj),但F#推断o实际上可能属于任何类型'a,从而导致{{1}类型的通用活动模式}。由于bool -> Choice<unit,'a -> obj>是一个自由类型变量,因此F#不接受此活动模式定义。如果您执行以下操作,则可以看到类似的问题:

'a

同样,解决方案是将定义单一化:

let (|T|F|) b =   
  if b then T else F []