F#中的引号和模式匹配

在新的控制台应用程序中,只需粘贴以下代码就会导致异常“参数不是可识别的方法名称”.

>以下代码是否适用于您的安装?
>小丑:你知道为什么它对我不起作用的原因吗?

// Learn more about F# at http://fsharp.net
// See the 'F# Tutorial' project for more help.
let somefunction1 arg  = ()
let somefunction2 ()   = ()

open Quotations.DerivedPatterns

let test() =
   let d =  <@ somefunction1() @>
   let e =  <@ somefunction2() @>

   match d with
   | SpecificCall <@ somefunction1() @> (a,b ,c) -> printfn "somefunction"
   | _                                           -> printfn "something else"
   match d with
   | SpecificCall <@ somefunction1   @> (a,b ,c) -> printfn "somefunction"
   | _                                           -> printfn "something else"

   match e with
   | SpecificCall <@ somefunction2() @> (a,b ,c) -> printfn "somefunction"
   | _                                           -> printfn "something else"

   //THIS FAILS HERE saying "The parameter is not a recognized method name"
   match e with
   | SpecificCall <@ somefunction2   @> (a,b ,c) -> printfn "somefunction"
   | _                                           -> printfn "something else"


[<EntryPoint>]
let main argv = 
    test()
    printfn "%A" argv
    0 // return an integer exit code

查看编译器中定义的活动模式SpecificCall的定义,我发现:

 [<CompiledName("SpecificCallPattern")>]
    let (|SpecificCall|_|) templateParameter = 
        // Note: precomputation
        match templateParameter with
        | (Lambdas(_,Call(_,minfo1,_)) | Call(_,minfo1,_)) ->
            let isg1 = minfo1.IsGenericMethod 
            let gmd = if isg1 then minfo1.GetGenericMethodDefinition() else null

            // end-of-precomputation

            (fun tm -> 
               match tm with
               | Call(obj,minfo2,args) 
#if FX_NO_REFLECTION_METADATA_TOKENS
                  when (minfo1.MethodHandle = minfo2.MethodHandle &&
#else               
                  when (minfo1.MetadataToken = minfo2.MetadataToken &&
#endif                  
                        if isg1 then 
                          minfo2.IsGenericMethod && gmd = minfo2.GetGenericMethodDefinition()
                        else
                          minfo1 = minfo2) -> 
                   Some(obj,(minfo2.GetGenericArguments() |> Array.toList),args)
               | _ -> None)
        | _ -> 
            invalidArg "templateParameter" (SR.GetString(SR.QunrecognizedMethodCall))

最佳答案 随便,对我来说没问题……你有可能以某种方式隐藏了var的原始定义吗?例如,以下自包含示例适用于我:

let var<'a>() = Unchecked.defaultof<'a>

match <@ var<int>() @> with
| Quotations.DerivedPatterns.SpecificCall <@ var @> (obj,_,[]) ->
    printfn "var"
| _ -> printfn "something else"
点赞