【问题标题】:Typing a record field to hold a function with type arguments键入记录字段以保存具有类型参数的函数
【发布时间】:2018-10-09 23:26:28
【问题描述】:

给定一个定义为let get<'T> var1 var2 : 'T option 的函数,该函数将分配给记录字段的类型签名应该是什么?

我尝试了type MyType = {AFunc<'T> : obj -> obj -> 'T option} 的各种排列,但找不到任何可以让我引入类型参数的变体。

我可以这样做type MyType = {AFunc: obj -> obj -> obj option},这将让我创建记录 {AFunc = get} 但由于缺少类型参数而无法应用该函数。

【问题讨论】:

    标签: f#


    【解决方案1】:

    你的问题有点模棱两可。您是否希望能够将get<'t> 存储在每个记录的一个特定't 的记录中,或者您是否希望记录本身存储像get<_> 这样的“通用”函数?

    如果是前者,那么TeaDrivenDevanswer 将起作用。

    如果是后者,那么使用 F# 的类型系统就没有完全直接的方法:记录字段不能是通用值。

    但是,有一个相当干净的解决方法,即使用泛型方法声明接口类型并将接口的实例存储在您的记录中,如下所示:

    type OptionGetter = abstract Get<'t> : obj->obj->'t option
    type MyType = { AFunc: OptionGetter }
    let get<'t> var1 var2 : 't option = None // your real implementation here
    let myRecord = { AFunc = { new OptionGetter with member this.Get v1 v2 = get v1 v2} }
    let test : int Option = myRecord.AFunc.Get "test" 23.5
    

    【讨论】:

    • 啊,我什至没有考虑过这种歧义。这是我想到的第二个。
    【解决方案2】:

    您必须使记录类型本身具有通用性;只有这样'T 才能被定义和使用。

    type MyType<'T> = { AFunc : obj -> obj -> 'T option }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2022-08-23
      • 2016-06-08
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-12-03
      • 2010-10-04
      相关资源
      最近更新 更多