如何在类型参数中使用区分联合分支?

时间:2016-11-09 08:32:55

标签: generics f# discriminated-union

假设我在F#中有这样的类型:

type public Expression =
    | Identifier of string
    | BooleanConstant of bool
    | StringConstant of string
    | IntegerConstant of int
    | Vector of Expression list
    // etc...

现在我想使用这种类型来构建地图:

definitions : Map<Identifier, Expression>

但是,这会产生错误:

  

未定义类型'标识符'

如何将我的类型案例用作类型参数?

2 个答案:

答案 0 :(得分:5)

Identifier案例构造函数,而不是类型。它实际上是一个类型为string -> Expression的函数。案例的类型为string,因此您可以将definitions定义为

type definitions : Map<string, Expression>

答案 1 :(得分:2)

如果您希望密钥是特定类型(即)而不仅仅是另一个字符串,还有另一种方法。您可以创建StringID类型,也可以将其进一步包装到Expression:

type StringId = Sid of string
type  Expression =
    | StringId of StringId
    | BooleanConstant of bool
    | StringConstant of string
    | IntegerConstant of int
    | Vector of Expression list

这将允许您通过以下任一方式创建地图:

let x = Sid "x"
[StringId x ,BooleanConstant true] |> Map.ofList
//val it : Map<Expression,Expression> = map [(StringId (Sid "x"), BooleanConstant true)]

[x,BooleanConstant true] |> Map.ofList
//val it : Map<StringId,Expression> = map [(Sid "x", BooleanConstant true)]

也就是说,将密钥保持为简单字符串肯定不那么复杂。