【问题标题】:Abstract type definitions f#抽象类型定义 f#
【发布时间】:2017-05-10 09:18:33
【问题描述】:

我希望在接口或抽象类中定义几个类型,但未指定实现。 然后我想在另一个接口中继承这个接口,这样我就可以在 interface2 中使用第一个接口中定义的类型指定我的方法。

例如:

type Interface1 =
      type MyType1
      type MyType2

type Interface2 =
      inherit Interface1
      abstract member method1 : MyType1*MyType2 -> int


Module MyModule =

我的想法是我希望模块实现 interface2,所以它应该实现 MyType1 和 MyType2,以及 method1。

我没有在签名文件中做所有这些的原因是因为我希望能够在 c# 中实现 type1 和 2,但是实现 Interface1。

谁能帮我解决这个问题?

【问题讨论】:

  • 首先,签名文件不像头文件那样工作,所以我认为您的方法不太正确
  • 听起来您正在尝试使用 ML 风格的模块系统 - F# 并不真正支持这一点,人们通常使用接口或其他抽象机制,具体取决于具体情况 - 什么是您要解决的原始问题是什么?
  • 我们正在尝试制作可用于开发安卓游戏的通用代码库。我们已经制作了一个通用的 viewmode-controller 部分,现在我们正在尝试为模型定义一个可用于所有实现的接口。 IE。 MyType1MyType2 在 interface/abstract 类中未指定,但会为每个不同的游戏获取一个特定的实现,可以根据你的需要而有所不同。

标签: c# inheritance interface f# abstract-class


【解决方案1】:

我认为你真正想要的是使用泛型:

type Interface2<'T1,'T2> =
      abstract member method1 : 'T1*'T2 -> int

这里根本不需要Interface1。然后,如果在 C# 中(或在 F# 中)实现了 Type1Type2,那么您的 C# 类可以从 Interface2&lt;Type1,Type2&gt; 继承,并且一切就绪。

编辑:如果我正确理解了您的评论,您希望对 'T1'T2 设置一些约束,以便它们实现特定的接口。所有这些的通用名称('T1Type1 等等)开始让我感到困惑,所以我将使用特定名称作为示例。假设您有一个通用的IKeyboard 接口和一个通用的IMouse 接口,并且您希望您的库的用户为您的方法实现一个特定的键盘和鼠标类。换句话说,上面的'T1 类型必须从IKeyboard 派生,而上面的'T2 类型必须从IMouse 派生。在这种情况下,type constraints 就是您要查找的内容:

type IKeyboard = class end
type IMouse = class end

type IInputDevices =
    abstract member getInput<'K,'M when 'K :> IKeyboard and 'M :> IMouse> : 'K*'M -> int

【讨论】:

  • 我认为这可行,但我想要一个指定类型的接口,以便我们库的用户知道他必须在 c# 和 f# 中实现这些类型。这有可能吗?我还想在接口中定义Type1Type2 中的其他类型,但我似乎找不到在接口中定义类型的任何方法
  • 我刚刚在我的答案中添加了我认为您正在寻找的内容。
  • 我很难理解你的答案,所以我会尝试更深入地解释我的问题。我想让用户实现两种类型,PositionElement。他们应该始终指定这些类型,但他们可以决定它们应该是什么。 (例如intchar...)。然后我想实现其他类型GameBoardGameMove。这些应该始终是GameBoard = Element listGameMove = Position * Element。我还想实现取决于我的类型的方法。例如。 IsValidGameMove : GameMove -&gt; boolCreateGameBoardFromList : Element list -&gt; GameBoard
  • 我可以用签名文件完全实现这一点,但是当我希望 c# 代码也能够创建 PositionElement 类型的对象时,我遇到了问题
  • 那么我想我同意 Tomas Petricek 一周前的评论:不幸的是,我认为你不能在 F# 的类型系统中按照目前的方式做你想做的事。听起来您需要能够编写module Foo&lt;'Position,'Element&gt;,然后在您的模块中使用这些类型'Position'Element(最终,您的模块的用户将定义这些泛型类型)。由于 F# 模块编译为 .Net 静态类,理论上是可能的,但我认为 F# 类型系统目前不允许这样做。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-09-03
  • 1970-01-01
相关资源
最近更新 更多