行动<t,u>和'T - &gt; 'U - &gt;单位转换</t,u>

时间:2014-11-06 23:47:37

标签: f#

在F#中,当调用以Action<T,U>为参数的C#方法时,我原以为我应该使用类似(fun (x, y) -> ())的东西。但实际上它只接受(fun x y -> ())

前者为何失败?它的行为更像目标代表。

将FSharpFun提供给采用Delegate的方法时实际发生了什么。它似乎不会执行隐式upcast,因为Delegate不是FSharpFun的接口或基类。

是隐式转换吗?但我认为F#只做了明确的转换。

1 个答案:

答案 0 :(得分:2)

委托的参数列表不是元组。如果F#允许new Action<_,_>(fun (_, _) -> ())无效代码),那么这就不会少了。如果允许这样做,将元组转换为单元的F#函数将转换为具有两个参数和void返回类型的CLI委托。在实际的F#中,如你所说,有效的形式是提供一个带有两个curried参数和单位输出的函数。

您可以创建一个以元组作为输入的委托,但它具有不同的签名(并且对于互操作既不是最佳的,也不是在F#中使用):

type MyDelegate = delegate of (int * int) -> unit
new MyDelegate(fun (a, b) -> ())

要了解F#如何处理委托构造,请参阅F#规范3.0,第8.13.7节&#34;第一次类型导向转换&#34; (或第14.4节) Gustavo也在问题的评论中指出了这一点。我引用:

  

假设:

     
      
  • 委托类型D的形式参数

  •   
  • 已知类型ty_1的实际参数farg - &gt; ... - &gt; ty_n - &gt; RTY

  •   
  • 委托类型D

  • 的Invoke方法的n个参数   
     

然后:

     
      
  • 该参数被解释为它被写入:   新D(有趣$ arg_1 $ ... arg_n - &gt; farg arg_1 ... arg_n)
  •   

最后一行是对象构造表达式。这些在第6.4.2节中处理,它基本上说明了委托构造的参数应该以curry形式提供。