如何正确覆盖受约束的方法

How do I properly override a constrained method

如何重写以下代码中的方法 Zero,以便我可以 return Euro(0)type Euro[=14 中的定义=]

[<AbstractClass>] 
type Currency () =
    abstract member Zero<'T when 'T :> Currency > : unit -> 'T

type Euro (value: int) =
    inherit Currency()
    member this.Value = value
    override this.Zero() = Euro(0) :> _

您是否尝试过将通用约束提升到 class 级别?

[<AbstractClass>] 
type Currency<'T when 'T :> Currency<'T>>() =
    abstract member Zero : unit -> 'T

type Euro (value: int) =
    inherit Currency<Euro>()
    member this.Value = value
    override this.Zero() = Euro(0)

虽然 self-referencing 泛型对我来说总是很奇怪,但这就是它在 C# 中的实现方式。

F# 中还有 'roll your own typeclass' 技术。基本上你的抽象类型的(实例和静态)成员成为 'typeclass' 记录的字段,并且该记录的值是类型类实例。您可以有一个 'euro' 实例、一个 'dollar' 实例,等等:

module Currency =
  type t<[<Measure>] 'a> =
    { zero : decimal<'a>; from : decimal -> decimal<'a> }

  /// Helper function to easily create typeclass instances for any
  /// currency.
  let make<[<Measure>] 'a> (curr_unit : decimal<'a>) : t<'a> =
    { zero = curr_unit - curr_unit; from = ((*) curr_unit) }

  [<Measure>] type euro
  let euro : t<euro> = make 1m<euro>

  [<Measure>] type dollar
  let dollar : t<dollar> = make 1m<dollar>

F# 的独特之处在于,传递给每个类型类实例的类型参数实际上可以是适合货币的度量类型。