向(F#)记录中添加“抽象”方法

O.F*_*.F. 1 f# record abstract c#-to-f#

我创建了以下记录,以尝试将C#类转换为F#:

    type Days = Days of int
    type Value = Value of int
    type Item = {
        Name: string
        Expires: Days
        Value: Value
    }
Run Code Online (Sandbox Code Playgroud)

问题是我还需要每个Item都有一个“方法”,以运行另一个尚未定义的函数,该函数handleDevalue作用于Item本身以操纵Item的Value值。

handleDevalue功能是依赖于Expires这样每个项目的实施,这将是不同的,唯一的共同点是函数的名称和签名(该项目的性质和Item -> Item)。
在C#代码上,我正在翻译此方法,该方法abstractItem类上定义,并在实例化的每个项目(其中每个项目都是从继承的子类Item)中覆盖。

我尝试过的,直到现在都没有成功

  1. 在记录上添加一个抽象方法:...} with abstract handleDevalue: Item -> Item
    1.1 失败的原因:IDE告诉我“不能在此处添加抽象作为增强”(或类似的效果)。(我对F#的了解还不够,甚至不知道它是什么意思,但是编译器不会让它如此编译...否)。
  2. handleDevalue作为功​​能添加到记录中:{... HandleDevalue: Item -> Item...}
    2.1。失败原因:此功能取决于Expires属性。显然,记录的字段彼此独立,此外...函数将如何“知道”要对哪个项目执行操作(应该对项目本身进行操作)?this在“实例化”记录时(即no {...handleDevalue = fun this -> <some implementation code here>)实现函数时,不允许使用关键字。
  3. 我记得在我创建的每个项目上都定义了函数(无论如何,我还是应该这样),但这并不是利用类型系统对我有利。
    我希望编译器强迫我实现该功能,并在不这样做的情况下提醒我。

这些方法失败了,我不知道该如何前进。

感谢您提前提出任何建议。

Gur*_*ran 5

我不确定您要在这里完成什么,但是我会给您一个机会。

为什么不使用区别联合而不是继承来做类似的事情?

type Days = Days of int
type Value = Value of int
type Item = {
    name: string
    expires: Days
    value: Value
}
type ItemType =
| FooItem of Item
| BarItem of Item
| BazItem of Item
// ...
let deValue item =
    match item with
    | FooItem i ->
        {
             name = i.name
             expires = i.expires -1
             value = i.value -1
        } |> FooItem
    | BarItem i ->
        {
             name = i.name
             expires = i.expires -1
             value = i.value -10
        } |> BarItem
    | // etc
Run Code Online (Sandbox Code Playgroud)