(这种情况似乎没有被先前的线程回答,或者至少对我来说不是显而易见的,关键的区别是对高阶类型的递归要求)
(我已经重写了这个问题,以期给出一些行之有效的方法……但很痛苦……而不是对约束的含糊追求)
我有一些类似这样的代码(但是类型很多)...
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
理想情况下,option <>的方法将/应该实施一次,例如...
static member typeOf<'a>(i : TypeOf<option<'a>>) = 4 + TypeOfOperator.typeOf(TypeOf<'a>())
即写过一次...但这显然不能编译。
f#中是否可以实现上述方法/功能?
答案 0 :(得分:0)
根据您在临近答案中显示的typeOf<'a>
函数,有什么不同的方法呢?您是否考虑过这样的事情:
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
。
答案 1 :(得分:0)
我已经做到了,它是基于先前的答案,但确实需要额外的痛苦。
这是实际的代码(因此返回类型arent ints不再...但是希望其他类型也能获得成功)
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 >())
前两行是如何处理递归调用的示例,这些递归调用将解构高阶类型以获取参数并基于此调用方法。
最终的typeof只是删除这个幻影(?)T参数的好方法,该参数用来欺凌类型推断引擎,使其在正确的位置查找。
现在我们可以致电...
let x = T.typeOf<seq<string>>()