我需要在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)
所以我认为问题在于color并bgcolor共享一个共同的属性值:transparent它反映在数据类型中colorvalue并bgcolorvalue共享构造函数Transparent.实际上,它们共享所有值,因此所有构造函数.
很容易看出,在同一范围内尝试在不同类型中使用相同的构造函数会产生类型推断的问题.例如,应该是什么类型的
fun heat Transparent = Yellow
| heat Yellow = Red
| heat Red = Blue
| heat Blue = Blue;
Run Code Online (Sandbox Code Playgroud)
是?colorvalue ->colorvalue或者bgbcolorvalue -> bgbcolorvalue或colorvalue -> bgbcolorvalue或bgbcolorvalue -> 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中运行的,并说明了现在没有冲突.
| 归档时间: |
|
| 查看次数: |
161 次 |
| 最近记录: |