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

How do I use a discriminated union branch in a type parameter?

假设我在 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>

然而,这给出了错误:

The type 'identifier' is not defined

如何将类型大小写用作类型参数?

Identifiercase 构造器,不是类型。它实际上是一个类型为 string -> Expression 的函数。 case的类型是string,所以可以定义definitions

type definitions : Map<string, Expression>

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

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)]

也就是说,将密钥保存为一个简单的字符串肯定没那么复杂。