【问题标题】:Subscribing to c# Events in F# With Partial Applications使用部分应用程序在 F# 中订阅 c# 事件
【发布时间】:2020-10-22 18:13:42
【问题描述】:

在敲了几个小时的头之后,我有了这个工作。现在我正试图了解原因。

这是来自 c# 库的事件定义:

internal readonly AsyncEvent<Func<SocketMessage, Task>> _messageReceivedEvent = new AsyncEvent<Func<SocketMessage, Task>>();

它的唯一工作方式是直接传入 (fun -> ):

        helper.client.add_MessageReceived
            (fun msg ->
                processMsg msg)

不能参数化:

        let x = 
            (fun msg ->
                processMsg msg)
        
        helper.client.add_MessageReceived x

我最初尝试只传递 processMsg 函数。它看起来像正确的签名:

        helper.client.add_MessageReceived processMsg

【问题讨论】:

  • add_MessageReceived 的确切签名是什么?
  • F# intellisense 说BaseSocketClient.add_MessageReceived(value: System.Func&lt;SocketMessage, Task&gt;) : unit
  • 我的函数是val processMsg : (SocketMessage -&gt; Task)

标签: f# c#-to-f#


【解决方案1】:

那是因为System.Funcdelegate

当您将 lambda 函数传递给 add_MessageReceived 时,lambda 会隐式转换为 System.Func

但在其他情况下,您需要明确地进行转换:

let x = System.Func<_, _> (fun msg -> processMsg msg)
helper.client.add_MessageReceived x

【讨论】:

  • 好的,我认为部分应用程序是委托。这也适用helper.client.add_MessageReceived (System.Func&lt;SocketMessage, Task&gt; (processMsg))
  • 相对于 OO,我真的很喜欢函数式范式,但我每隔几天就会不断尝试一些事情,这真的让我慢了下来。
  • 别担心。这是正常的。当我们开始学习 FP/F# 时,我和我的许多朋友也遇到了这种情况。
  • 嗯,你非常有帮助,我很感激。到 System.Func 的隐式转换确实是不一致的,并引起了所有的混乱。就像在“字符串电子邮件”要求您确认构造函数 let x = Email "string" 的语言中,让 Func&lt;&gt; (fun -&gt; ) 成为基于隐式的上下文是不好的。
  • 我们在 F# 中使用委托只是因为有时我们需要使用 C# 代码或其他 .NET 库。如您所见,许多不受欢迎的功能(如 null、异常...)在 F# 代码中仍然可用。纯 FP 代码是美丽的恕我直言。
猜你喜欢
  • 2010-12-06
  • 1970-01-01
  • 1970-01-01
  • 2020-01-24
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-02-22
相关资源
最近更新 更多