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

And*_*dry 1 ml sml

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

color: red | yellow | blue | transparent
align: left | center | right
bgcolor: red | yellow | blue | transparent
Run Code Online (Sandbox Code Playgroud)

我创建了这个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
Run Code Online (Sandbox Code Playgroud)

当我在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
Run Code Online (Sandbox Code Playgroud)

我猜

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

  • 这是失败的原因吗?
  • 在任何情况下,我该怎么做来描述我的系统?

Joh*_*man 6

很容易看出,在同一范围内尝试在不同类型中使用相同的构造函数会产生类型推断的问题.例如,应该是什么类型的

fun heat Transparent = Yellow
|   heat Yellow = Red
|   heat Red = Blue
|   heat Blue = Blue;
Run Code Online (Sandbox Code Playgroud)

是?colorvalue ->colorvalue或者bgbcolorvalue -> 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;
Run Code Online (Sandbox Code Playgroud)

然后你可以做以下事情:

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

- val b = BGBColor.Transparent;
val b = Transparent : BGBColor.value
Run Code Online (Sandbox Code Playgroud)

最后这个是在SML/NJ REPL中运行的,并说明了现在没有冲突.