在 SML 中解析具有多种数据类型的元组列表
Parsing a list of tuples with mutliple data types in SML
所以我想要一个包含一个 int 键和一个 int 或布尔值的元组列表:
[(0, 1), (1, 2), (2, true), (3, 4), ...]
我一直在尝试编写将元组添加到列表的函数,以及 return 给定键的值。例如:
getValue(2, [(0,1),(1,true),(2,3),(3,4)]); -> returns 3
getValue(1, [(0,1),(1,true),(2,3),(3,4)]); -> returns true
addValue([(0,1),(1,true),(2,3),(3,4)], (4, false)); -> [(0,1),(1,true),(2,3),(3,4),(4,false)]
addValue([(0,1),(1,true),(2,3),(3,4)], (2, 5)); -> [(0,1),(1,true),(2,5),(3,4)]
这是我到目前为止生成的代码,在严格使用 int 或 bool 时工作正常。当我将它们组合起来时,出现错误“运算符和操作数不一致”。
fun getValue (key1, list) =
let
fun parse [] = 0
| parse ((key, v)::list) =
if key1 = key then v
else parse list;
in
parse list
end;
fun addValue([], (key1, v1)) = [(key1, v1)]
| addValue((key, v)::a, (key1, v1)) =
if key1 = key then (key1, v1)::a
else (key, v)::addValue(a, (key1, v1));
我对 SML 很陌生,这甚至不可能。只是想问问周围。谢谢!
编辑
这不起作用的原因是什么?
datatype denotable_value = Boolean of bool
| Integer of int;
fun accessStore ( loc1, (env, s : (int * denotable_value) list) ) =
let
val msg = "Error: accessEnv " ^ Int.toString(loc1) ^ " not found.";
fun aux [] = error msg
| aux ( (loc, v)::s ) =
if loc1 = loc then v
else aux s;
in
aux s
end;
accessStore(0, ([], [(0, 1), (1, true), (2, 3)]));
的确,你所描述的是不可能的;标准 ML 只使用静态类型,这意味着每个表达式都需要具有唯一且定义明确的类型,以便在运行时理解值。 [(0, 1)]
可以,类型为 (int * int) list
; [(2, true)]
可以,类型为 (int * bool) list
;但是 [(0, 1), (2, true)]
不行,因为像 (List.nth ([(0, 1), (2, true)], i)
这样的表达式(采用列表的 ith 元素)必须是 int * int
或int * bool
取决于 i
的值,这不是类型系统的工作方式。
相反,您所做的是为需要为整数或布尔值的值定义一个新的代数数据类型:
datatype intOrBool = INT of int | BOOL of bool
并使用适当的构造函数将这些值包装在该类型中:
[(0, INT 1), (1, INT 2), (2, BOOL true), (3, INT 4)] : (int * intOrBool) list
(当然,您会希望使用比 intOrBool
、INT
和 BOOL
更好的名称 — 更适合您的应用程序;但希望上面的内容能为您提供帮助这个想法。)
所以我想要一个包含一个 int 键和一个 int 或布尔值的元组列表:
[(0, 1), (1, 2), (2, true), (3, 4), ...]
我一直在尝试编写将元组添加到列表的函数,以及 return 给定键的值。例如:
getValue(2, [(0,1),(1,true),(2,3),(3,4)]); -> returns 3
getValue(1, [(0,1),(1,true),(2,3),(3,4)]); -> returns true
addValue([(0,1),(1,true),(2,3),(3,4)], (4, false)); -> [(0,1),(1,true),(2,3),(3,4),(4,false)]
addValue([(0,1),(1,true),(2,3),(3,4)], (2, 5)); -> [(0,1),(1,true),(2,5),(3,4)]
这是我到目前为止生成的代码,在严格使用 int 或 bool 时工作正常。当我将它们组合起来时,出现错误“运算符和操作数不一致”。
fun getValue (key1, list) =
let
fun parse [] = 0
| parse ((key, v)::list) =
if key1 = key then v
else parse list;
in
parse list
end;
fun addValue([], (key1, v1)) = [(key1, v1)]
| addValue((key, v)::a, (key1, v1)) =
if key1 = key then (key1, v1)::a
else (key, v)::addValue(a, (key1, v1));
我对 SML 很陌生,这甚至不可能。只是想问问周围。谢谢!
编辑
这不起作用的原因是什么?
datatype denotable_value = Boolean of bool
| Integer of int;
fun accessStore ( loc1, (env, s : (int * denotable_value) list) ) =
let
val msg = "Error: accessEnv " ^ Int.toString(loc1) ^ " not found.";
fun aux [] = error msg
| aux ( (loc, v)::s ) =
if loc1 = loc then v
else aux s;
in
aux s
end;
accessStore(0, ([], [(0, 1), (1, true), (2, 3)]));
的确,你所描述的是不可能的;标准 ML 只使用静态类型,这意味着每个表达式都需要具有唯一且定义明确的类型,以便在运行时理解值。 [(0, 1)]
可以,类型为 (int * int) list
; [(2, true)]
可以,类型为 (int * bool) list
;但是 [(0, 1), (2, true)]
不行,因为像 (List.nth ([(0, 1), (2, true)], i)
这样的表达式(采用列表的 ith 元素)必须是 int * int
或int * bool
取决于 i
的值,这不是类型系统的工作方式。
相反,您所做的是为需要为整数或布尔值的值定义一个新的代数数据类型:
datatype intOrBool = INT of int | BOOL of bool
并使用适当的构造函数将这些值包装在该类型中:
[(0, INT 1), (1, INT 2), (2, BOOL true), (3, INT 4)] : (int * intOrBool) list
(当然,您会希望使用比 intOrBool
、INT
和 BOOL
更好的名称 — 更适合您的应用程序;但希望上面的内容能为您提供帮助这个想法。)