【发布时间】:2021-01-16 15:32:35
【问题描述】:
在 F# 组件设计指南的 Use interfaces to group related operations 部分中,它列出了具有泛型类型参数 'T 的方法的此接口类型。
type Serializer =
abstract Serialize<'T> : preserveRefEq: bool -> value: 'T -> string
abstract Deserialize<'T> : preserveRefEq: bool -> pickle: string -> 'T
object expressions 参考部分和interfaces 参考部分没有列出如何使用通用'T 参数实现接口的任何示例。 Generics 参考部分的末尾确实有一个简短的示例...我仍然难以编写反映该示例的代码。
我知道如何实现具有泛型类型的接口,而不是具有泛型类型参数的接口。
这是一个简单的玩具示例,我一直在尝试实现以了解如何做到这一点:
type Foo = Foo of string
type Bar = Bar of string
let unwrapFoo (Foo foo) = foo
let unwrapBar (Bar bar) = bar
type IWrapper =
abstract member Unwrap<'T> : 'T -> string
abstract member Wrap<'U> : string -> 'U
尝试实现 IWrapper 是我遇到编译器错误的地方:
let wrapper =
{ new IWrapper with
member this.Unwrap<Foo>(foo: Foo) = unwrapFoo foo
member this.Wrap<Bar> string = Bar string }
wrapper let 绑定会给我一个编译器错误:Unexpected identifier in pattern. Expected infix operator, quote symbol or other token.
我在实现IWrapper 的其他尝试给了我这个编译器错误:typecheck error The member 'Unwrap<'T> : Foo -> string' does not have the correct type to override the corresponding abstract method. The required signature is 'Unwrap<'T> : 'T -> string'.
let wrapper =
{ new IWrapper with
member this.Unwrap<'T>(foo: Foo) = unwrapFoo foo
member this.Wrap<'U> string = Bar(string) }
非常感谢您对实现此接口类型的任何帮助以及对阅读编译器错误消息的洞察力(我确信这是在向我解释如何解决我的问题)。谢谢大家!
【问题讨论】:
-
您的声明应该是
member this.Unwrap<'T>(foo: 'T) = ...,尽管您将无法调用unwrapFoo,因为foo的类型错误。Wrap和Unwrap需要适用于所有类型,因此您不能将实现专门用于某些特定类型,例如Foo。
标签: f#