我有以下功能。它用于将字符串的某些部分转换为Discriminated union情况。我有特定的,并且已经重复和推广代码。
let extractor ty (characters:list<char>)=
//find the UnionCaseInfo for the named subtype of Token (ty)
let uci = (Microsoft.FSharp.Reflection.FSharpType.GetUnionCases(typeof<Token>) |> Array.filter (fun u->u.Name.Equals(ty))).[0]
//construct the chosen type from the passed in ElementValue (l)
let maker l = Microsoft.FSharp.Reflection.FSharpValue.MakeUnion(uci,[|l|]) :?> Token
match characters with
| '('::t -> match t with
| '!'::t2 -> match t2 with
| '\''::t3 -> let (entries,rest) = t3 |> entriesUntil '\''
(maker(LiteralInsertion(stringOf entries)),trimHeadIf ')' rest)
| '\''::t2 -> let (entries,rest) = t2 |> entriesUntil '\''
(maker(LiteralValue(stringOf entries)),trimHeadIf ')' rest)
| '$'::t2 -> let (entries,rest) = t2 |> entriesUntil ')'
(maker(CaptureValue(stringOf entries)), rest)
| _ -> failwith "Expecting !'Insertion', $Capture or 'Literal' following ("
| l -> (maker(DataCellValue),l)
我想做以下事情:
let extractor<'T> (characters:list<char>) =
etc...
| l -> ('T(DataCellValue),l)
但这没有用(所以我最终采用了反思方法)
事先提前答案 0 :(得分:1)
type DU =
| A
| B
let inline create v = (^a : (new : DU -> ^a) v)
type Ty (du: DU) = class end
let ty: Ty = create A
所以,在你的情况下,它可能看起来像这样
type DU1 =
| LiteralInsertion
| DataCellValue
type Token (du: DU1) = class end
let inline extractor ty (characters: list<char>) : 'a =
match characters with
| '(' :: t -> (^a : (new : DU1 -> ^a) LiteralInsertion)
| l -> (^a : (new : DU1 -> ^a) DataCellValue)
let x: Token = extractor "ty" []
如果没有帮助,请显示完整代码(我的意思是类型令牌和DUs)。