gpt4 book ai didi

F# - 类型参数不能用作类型构造函数

转载 作者:行者123 更新时间:2023-12-02 01:50:32 25 4
gpt4 key购买 nike

我正在使用 Akkling 在 F# 中工作,因此我可以使用 Akka.net 上的强类型 actor,但我在 F# 中遇到了设计限制,我想知道是否有一种优雅的方法可以解决这个问题。

以我的根消息类型为例,我真的不想在那里有 IActorRef<_> 因为这种类型将存在于一个公共(public)库中,并且不应该知道它使用的消息系统。另外,为了方便测试,我不想创建整个 actor 系统(或测试套件)。

type MessageType =
| World of WorldMessage
| Location of IActorRef<LocationMessage> * LocationMessage
| Client of IActorRef<LocationMessage> * ClientMessage

一个可怕的解决方法是:

type MessageType<'LocationActor, 'PlayerActor, 'ClientActor> =
| World of WorldMessage<'ClientActor>
| Location of 'LocationActor * LocationMessage<'ClientActor>
| Client of 'ClientActor * ClientMessage<'LocationActor>

理想情况下,我希望这样,但存在语言限制(错误:类型参数不能用作类型构造函数):

type MessageType<'a> =
| World of WorldMessage<'a>
| Location of 'a<LocationMessage> * LocationMessage
| Client of 'a<LocationMessage> * ClientMessage

最佳答案

评论中已经提到了实际的类型系统问题(缺少 HKT),但我认为它们并不是真正有必要解决这里的设计问题。

您不希望直接依赖 Akka.NET,但您仍然希望您的类型带有与消息一起使用 actor 引用的概念。一种解决方法是围绕 Actor 引入您自己的接口(interface)(作为实际的接口(interface)类型或一组函数,具体取决于您的上下文)。

因此,在您的通用库中,您拥有自己的 IMyActorRef 以及您认为 IActorRef 功能的合理通用子集:

type IMyActorRef<'msg> = 
abstract member Tell: ... -> ...
abstract member Ask: ... -> ...

并根据该接口(interface)定义您的消息类型(以及使用它的实际逻辑):

type MessageType =
| World of WorldMessage
| Location of IMyActorRef<LocationMessage> * LocationMessage
| Client of IMyActorRef<ClientMessage> * ClientMessage

然后在引用 Akka.NET 时提供它的实现。

关于F# - 类型参数不能用作类型构造函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50944604/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com