具有相同构造函数名称的标准 ML 数据类型中的类型冲突

Type clash in Standard ML datatype with same constructor name

我需要在 Standard-ML 中描述一种由属性和值组成的语言。我的 属性 系统由可以具有值的属性组成,例如:

color: red | yellow | blue | transparent
align: left | center | right
bgcolor: red | yellow | blue | transparent

我创建了这个试图描述这些属性的 sml 文件:

datatype colorvalue = Transparent
                    | Yellow
                    | Blue
                    | Red

datatype bgcolorvalue = Transparent
                      | Yellow
                      | Blue
                      | Red

datatype alignvalue = Left
                    | Center
                    | Right

(* Generic property: it can be any of the above *)
datatype property = Color of colorvalue
                  | BgColor of bgcolorvalue
                  | Align of alignvalue

(* Some values *)
val prop1: property = Color   Transparent
val prop2: property = BgColor Transparent

当我在 MoscowML 中编译时,我得到:

,File "c:\Users\myuser\documents\myproj\property.sml", line 21, characters 31-42:
! val prop1: property = Color   Transparent
!                               ^^^^^^^^^^^
! Type clash: expression of type
!   bgcolorvalue
! cannot have type
!   colorvalue

我的猜测

所以我认为问题在于 colorbgcolor 共享一个共同的 属性 值:transparent 这反映在数据类型 colorvaluebgcolorvalue 共享构造函数 Transparent。实际上它们共享所有值,因此所有构造函数。

很容易看出,尝试在同一范围内的不同类型中使用相同的构造函数会产生类型推断问题。比如

的类型应该是什么
fun heat Transparent = Yellow
|   heat Yellow = Red
|   heat Red = Blue
|   heat Blue = Blue;

是吗? colorvalue ->colorvaluebgbcolorvalue -> bgbcolorvaluecolorvalue -> bgbcolorvaluebgbcolorvalue -> colorvalue?

最简单的解决方法是对构造函数采用不同的命名约定。您还可以使用结构(这就是 SML 如何在基础库中保持名称 map 的不同用法而没有任何冲突)。类似于:

structure Color = struct
    datatype value = Transparent
                   | Yellow
                   | Blue
                   | Red
end

structure BGBColor = struct
    datatype value = Transparent
                   | Yellow
                   | Blue
                   | Red
end;

然后您可以执行以下操作:

- val a = Color.Transparent;
val a = Transparent : Color.value

- val b = BGBColor.Transparent;
val b = Transparent : BGBColor.value

最后一个是 运行 在 SML/NJ REPL 中,说明现在没有冲突。