嵌套泛型的 F# 编译错误



我有一个简单的包装器,用于向任意对象添加附加数据:

type Wrapper<'T>(data:'T) =
  member val Data:'T=data with get
  member val AdditionalProperty:int=0 with get

然后我在单向链表中使用这些元素,我想约束项目Wrapper<'T>,元素被定义:

type LListItem<'T>(data:Wrapper<'T>) =
  member val Data:Wrapper<'T>=data with get
  member val Prev:LListItem<'T> option = None with get, set

然后我假装用这个类管理链表:

 1| type LList<'T>()=
 2|   let mutable last:LListItem<Wrapper1<'T>> option = None
 3|   member x.Append(wrapped:Wrapper1<'T>)=
 4|     let item = new LListItem<'T>(wrapped)
 5|     match last with
 6|     | None -> 
 7|       last <- Some item
 8|     | Some l -> 
 9|       item.Prev <- last
10|      last <- Some item

但是在这种Append方法中,我这些编译错误:

  • 第 1 行:此类型参数的使用方式使其始终为"包装器

  • 第 1 行:此代码的通用性不如其注释所需的通用性,因为显式类型变量 'T' 无法泛化。它被限制为"包装器"。

  • 第 3 行:泛型成员 'Append' 已在此程序点之前以非统一实例化使用。请考虑对成员重新排序,以便首先出现此成员。或者,显式指定成员的完整类型,包括参数类型、返回类型以及任何其他泛型参数和约束。

我在这里做了一些根本错误的事情,但我不理解编译器消息。

您收到错误消息,因为类型推断以某种方式推断泛型类型参数'T始终被约束为Wrapper<'T>。当您有一些代码采用 'T 类型的值并将其传递到预期Wrapper<'T>的位置时,通常会发生这种情况。

在您的情况下,当您在LList类型中设置last时,会发生这种情况。类型注释定义类型LListItem<Wrapper<'T>> option

type LList<'T>()=
  let mutable last:LListItem<Wrapper<'T>> option = None

但是当你分配值时,参数是LListItem<'T> 。因此,您需要将上述行更改为:

type LList<'T>()=
  let mutable last:LListItem<'T> option = None

我怀疑LListItem<Wrapper<'T>>是一个错误,因为LListItem总是接受包装的参数。

编辑:解决此问题的另一种选择是更改LListItem,使其永远不会接受包装的参数 - 这就是古斯塔沃的答案所暗示的。

相关内容

  • 没有找到相关文章

最新更新