如何创建 OCaml/F# DU 类型,其中它的案例是其他案例的子集?
例如,我想制作一个符号表,其中包含不同的符号声明类型,例如程序类型、变量和函数。
乍一看,我可以看到一个变量包含它的类型,函数也包含一个类型和许多参数变量。所以我想使用 1 DU,而不是分隔到许多记录或别名:
type Symbol =
| TypeSymbol of id:string
| VariableSymbol of id:string * type':TypeSymbol
| FunctionSymbol of id:string * params':VariableSymbol list * type':TypeSymbol
但这是错误的,因为 DU 案例不能是其他案例的子集。如何重新格式化类型以声明 DU 案例相互递归?
最佳答案
对于 F#,最简单的解决方案是创建较小的单例 DU 并引用它们:
type T = T of id:string
type V = V of id:string * type':T
type Symbol =
| TypeSymbol of T
| VariableSymbol of V
| FunctionSymbol of id:string * params': V list * type':T
它通过分解的用法可能是这样的。
let rec print x =
match x with
| TypeSymbol (T typeId) ->
typeId
| VariableSymbol (V (varId, T typeId)) ->
sprintf "%s : %s" varId typeId
| FunctionSymbol (funId, params', T typeId) ->
let printedParams =
params'
|> List.map (VariableSymbol >> print)
|> String.concat ") -> ("
sprintf "%s = (%s) -> %s" funId printedParams typeId
关于f# - 递归区分联合案例类型,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44666981/