【问题标题】:function overloading, static type inherence and interface types函数重载、静态类型继承和接口类型
【发布时间】:2018-07-25 13:51:03
【问题描述】:

(这个场景似乎没有被前一个线程回答,或者至少不是以我显而易见的方式,关键的区别是对高阶类型的递归要求)

(我已经重写了这个问题以给出一些可行的东西......但很痛苦......而不是围绕约束的模糊愿望)

我有一些代码有点像这样(但还有更多类型)...

type TypeOfOperator = 
    static member typeOf(i : TypeOf<int>) = 1
    static member typeOf(i : TypeOf<string>) = 2
    static member typeOf(i : TypeOf<seq<int>>) = 3 + TypeOfOperator.typeOf(TypeOf<int>())
    static member typeOf(i : TypeOf<seq<string>>) = 3 + TypeOfOperator.typeOf(TypeOf<string>())
    static member typeOf(i : TypeOf<option<int>>) = 4 + TypeOfOperator.typeOf(TypeOf<int>())
    static member typeOf(i : TypeOf<option<string>>) = 4 + TypeOfOperator.typeOf(TypeOf<string>())

let x = TypeOfOperator.typeOf(TypeOf<int>())
let y = TypeOfOperator.typeOf(TypeOf<string>())
let z = TypeOfOperator.typeOf(TypeOf<seq<int>>())
let a = TypeOfOperator.typeOf(TypeOf<seq<string>>())

此代码有效!...对于原子类型(例如“int”),这种构造是非常固有的,但是高阶类型(例如 seq)的形成是公式化的...即一个常量“+”对参数类型的一些递归调用....但这似乎在 F# 中无法捕获,我不得不费力地手动实现代码。

理想情况下 option 的方法将/应该执行一次,例如....

static member typeOf<'a>(i : TypeOf<option<'a>>) = 4 + TypeOfOperator.typeOf(TypeOf<'a>())

即写过一次……但这显然不能编译。

f#中有没有办法实现上述方法/功能?

【问题讨论】:

  • 它显然也不适用于外部定义的类型......所以如果我想做 TypeOf......那么我无法将方法 ttype 静态附加到字符串。跨度>
  • 您能否发布一个您想要使用的语法示例以及您想要获得的结果?我不完全确定我理解您的预期功能应该做什么。
  • 是的,一定给我一个小时
  • 哦...那很好,我不认为你可以超载...让我上厕所

标签: f#


【解决方案1】:

根据您在近似答案中显示的typeOf&lt;'a&gt; 函数,另一种方法如何?你有没有考虑过这样的事情:

open System

let typeOf<'a> =
    match Type.GetTypeCode(typeof<'a>) with
    | TypeCode.Int32 -> 1
    | TypeCode.String -> 2
    | _ -> 0

这应该返回你所期望的:

typeOf<int> // 1
typeOf<string> // 2

如果您需要支持TypeCode 中未枚举的类型,您可以改用Type.GUID

【讨论】:

  • 但是你无法绑定任意类型的返回值,而且在编译时也不知道。
  • @Asti 没错,如果你写了typeOf&lt;SomethingUnexpected&gt;,它会编译,你只会在运行时得到0。如果需要为不受支持的类型获取编译器错误,那么对类型元数据进行模式匹配将不是一个好的解决方案。
  • 这可能会起作用......在一定程度上......事实上这是我开始的地方......但我需要处理像 seq......其中'a 是一个任何东西......所以我可以采用我想要匹配的所有类型,并执行它们的 seq 和它们的 option 等......
【解决方案2】:

我已经解决了这个问题,它基于之前的答案,但确实需要额外的痛苦。

这是实际代码(因此返回类型不再是整数......但希望其他人会得到 jist)

type T = T with
    static member typeOf(T,i : TypeOf<string>) : IType<string> = stringType()
    static member typeOf(T,i : TypeOf<int>) : IType<int> = intType()
    static member inline typeOf(T,t : TypeOf<seq< ^N >>) : IType<seq< ^N >> = seqType ((^T or ^N) : (static member typeOf: ^T * TypeOf< ^N > -> _) T, TypeOf< ^N >())
    static member inline typeOf(T,t : TypeOf<Option< ^N >>) : IType<Option< ^N >> = optionType ((^T or ^N) : (static member typeOf: ^T * TypeOf< ^N > -> _) T, TypeOf< ^N >())
    static member inline typeOf() : IType< ^N > = ((^T or ^N) : (static member typeOf: ^T * TypeOf< ^N > -> _) T, TypeOf< ^N >())

前 2 个内联示例说明了如何处理递归调用,解构高阶类型以获取参数并在此基础上调用方法。

最后的 typeof 只是为了删除这个用来欺负类型推理引擎寻找正确位置的幻影 (?) T 参数。

我们现在可以调用...

let x = T.typeOf<seq<string>>()

【讨论】:

猜你喜欢
  • 1970-01-01
  • 2018-10-04
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-12-01
  • 2013-02-19
  • 2014-03-05
  • 1970-01-01
相关资源
最近更新 更多