Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/fsharp/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/ssh/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
F# 模式匹配:匹配函数/子类型列表? 设f(O:obj)= 匹配 | :? (obj->列表)->“赢” | :? 列表->“列表!” |->“失败” Console.WriteLine(f(funx->[“lol”])) Console.WriteLine(f([“lol”]))_F# - Fatal编程技术网

F# 模式匹配:匹配函数/子类型列表? 设f(O:obj)= 匹配 | :? (obj->列表)->“赢” | :? 列表->“列表!” |->“失败” Console.WriteLine(f(funx->[“lol”])) Console.WriteLine(f([“lol”]))

F# 模式匹配:匹配函数/子类型列表? 设f(O:obj)= 匹配 | :? (obj->列表)->“赢” | :? 列表->“列表!” |->“失败” Console.WriteLine(f(funx->[“lol”])) Console.WriteLine(f([“lol”])),f#,F#,打印“fail”两次,我想应该是这样的,因为我给了我一个函数obj->list,它不是obj->list。有没有办法让他们匹配呢?在生成匿名函数之前,我可以将每个列表向上转换为一个列表,或者在将其放入列表之前,我可以将所有内容向上转换为obj 这两种方法中的任何一种都能起作用并使之匹配,但我认为这就是协方差/逆方差应该已经解决的问题?如果我弄错了,请纠正我。不幸的是,您无法使用任何内置模式匹配来解决此问题 确定obj值是否是某个F#函数的唯一方法是使用F#反射并调用类型上的FSharpType.

打印“fail”两次,我想应该是这样的,因为我给了我一个函数
obj->list
,它不是
obj->list
。有没有办法让他们匹配呢?在生成匿名函数之前,我可以将每个列表向上转换为一个
列表
,或者在将其放入列表之前,我可以将所有内容向上转换为
obj


这两种方法中的任何一种都能起作用并使之匹配,但我认为这就是协方差/逆方差应该已经解决的问题?如果我弄错了,请纠正我。

不幸的是,您无法使用任何内置模式匹配来解决此问题

确定
obj
值是否是某个F#函数的唯一方法是使用F#反射并调用类型上的
FSharpType.IsFunction
方法。您可以在示例中检查以下情况:

let f (O: obj) = 
    match O with
        | :? (obj -> list<obj>) -> "win"
        | :? list<obj> -> "list!"
        | _ -> "fail"

Console.WriteLine(f(fun x -> ["lol"]))
Console.WriteLine(f(["lol"]))
开放系统
打开Microsoft.FSharp.Reflection
设f(o:obj)=
设ty=o.GetType()
如果FSharpType.IsFunction(ty),则
让tyFrom,tyTo=FSharpType.GetFunctionElements(ty)
如果tyTo.IsGenericType&&tyTo.GetGenericTypeDefinition()=typedefof,则
printfn“赢”
其他的
printfn“错误的函数”
其他的
printfn“不是函数”
Console.WriteLine(f(funx->“lol”)//函数错误
Console.WriteLine(f(funx->[“lol”])//win
Console.WriteLine(f([“lol”])//不是函数
您可以将行为封装在一个F#active模式中,以使语法更好一些(并在类型上使用模式匹配)。然而,另一个问题是,这并没有给你一个可以用来动态调用函数的函数。我不认为有一个内置的库函数用于此,因此您可能需要使用.NET反射来动态调用
Invoke
方法

编辑:有类似的相关问题。一般的问题是,您正在匹配特定泛型类型的某些(任何)实例化,因此列表等也会出现相同的问题。例如,请参见:

F#不支持co/对冲。
open System    
open Microsoft.FSharp.Reflection    

let f (o : obj) =  
  let ty = o.GetType() 
  if FSharpType.IsFunction(ty) then
    let tyFrom, tyTo = FSharpType.GetFunctionElements(ty)
    if tyTo.IsGenericType && tyTo.GetGenericTypeDefinition() = typedefof<list<_>> then
      printfn "win"
    else 
      printfn "wrong function"
  else
    printfn "not a function"

Console.WriteLine(f(fun x -> "lol"))    // wrong function
Console.WriteLine(f(fun x -> ["lol"]))  // win
Console.WriteLine(f(["lol"]))           // not a function