SMLNJ:运算符和操作数不一致 [tycon 不匹配] - 用于列表分配
SMLNJ: Operator & operand don't agree [tycon mismtach] - for list assignment
我在SMLNJ中写了如下函数:
fun f(id : int, l : int list list) =
let
val i : int = length(l) - 1
in
while i > 0 do
(
if (exists(id, List.nth(l, i))) then
List.hd(List.nth(l, i)) := 1
else();
i = i - 1
)
end;
收到错误如下:
Error operator and operand don't agree [tycon mismatch]
operator domain: 'Z ref * 'Z
operand: int * [int ty]
in expression:
List.hd (List.nth (l,i)) := 1
我知道运算符域是函数所期望的,而操作数是提供的。
我认为这是因为 int
无法分配给 list
类型。但是,我不清楚 List.hdList.nth(l, i))
将如何导致除 int
.
以外的任何结果
请告知我如何修复此错误和支持逻辑。
SML/NJ 的错误消息并没有使这一点非常清楚。如果您将此代码放入 Moscow ML REPL,并包含您使用但未定义的函数 contains
,您将收到以下错误:
! Toplevel input:
! List.hd(List.nth(l, i)) := 1
! ^
! Type clash: expression of type
! int list list
! cannot have type
! 'a ref list list
您的程序失败,因为您将 int 值视为 int ref 值。
在函数式编程中,您通常会尽量避免可变变量(ref 值)。
详细说明您遇到的问题:
List.hd(List.nth(l, i)) := 1
表示“将 List.hd(List.nth(l, i))
返回的引用设置为 1
。因为 l
是一个 int 列表,然后 List.nth(l, i)
returns 那个(或崩溃)的第 i
个元素,它是一个 int 列表 。然后 List.hd(...)
取第一个元素(或崩溃),它是 int。不是 int ref。
要使此行正常工作,您需要 l : int ref list list
.
但你不想这样。
i = i - 1
是一个布尔表达式,即returns true
if i
等价于自身减1。这对任何整数。您可能打算从 i
中减去 1 并将结果放入 i
,但您不能这样做,因为 i
不是可变变量,并且更新 [=74] 的运算符=]ref 被称为 :=
.
如果您的问题是转换列表
val m = [ [ 1, 2, 3 ],
[ 4, 5, 6 ],
[ 7, 8, 9 ] ]
入榜
val n = [ [ 1, 2, 3 ],
[ 1, 5, 6 ],
[ 1, 8, 9 ] ]
那么一个简单的方法就是使用 List.map
:
val n = List.map (fn row => 1 :: List.drop (row, 1)) m
一种更手动的方法,在 迭代 上练习 递归 和 模式匹配 ,例如 while ... do
(只有当你有可变变量时才有效)和 部分函数 像 List.hd
和 List.nth
(可能会崩溃)可能是:
fun f [] = []
| f (row::m) = (1 :: List.drop (row, 1)) :: f m
val n = f m
如果你想要一个可变版本,请考虑 Array2
模块而不是 int list list.
这是一个 Array2
使用递归增加游标的解决方案:
fun appulate f from to =
if from > to then ()
else (f from; appulate f (from+1) to)
fun f col m =
appulate (fn row => Array2.update (m, row, col, 1))
0 (Array2.nRows m - 1)
fun show m =
Array2.appi Array2.RowMajor (fn (_, col, c) =>
print (Int.toString c ^ (if col + 1 = Array2.nCols arr then "\n" else "" )))
{base=arr,row=0,col=0,nrows=NONE,ncols=NONE};
val m' = Array2.fromList m
val n' = f 0 m'
val _ = show n'
我意识到我没有给出 while ... do
的任何示例,也没有给出 int ref 的任何集合ref
, !
和 :=
.
我在SMLNJ中写了如下函数:
fun f(id : int, l : int list list) =
let
val i : int = length(l) - 1
in
while i > 0 do
(
if (exists(id, List.nth(l, i))) then
List.hd(List.nth(l, i)) := 1
else();
i = i - 1
)
end;
收到错误如下:
Error operator and operand don't agree [tycon mismatch]
operator domain: 'Z ref * 'Z
operand: int * [int ty]
in expression:
List.hd (List.nth (l,i)) := 1
我知道运算符域是函数所期望的,而操作数是提供的。
我认为这是因为 int
无法分配给 list
类型。但是,我不清楚 List.hdList.nth(l, i))
将如何导致除 int
.
请告知我如何修复此错误和支持逻辑。
SML/NJ 的错误消息并没有使这一点非常清楚。如果您将此代码放入 Moscow ML REPL,并包含您使用但未定义的函数 contains
,您将收到以下错误:
! Toplevel input:
! List.hd(List.nth(l, i)) := 1
! ^
! Type clash: expression of type
! int list list
! cannot have type
! 'a ref list list
您的程序失败,因为您将 int 值视为 int ref 值。
在函数式编程中,您通常会尽量避免可变变量(ref 值)。
详细说明您遇到的问题:
List.hd(List.nth(l, i)) := 1
表示“将List.hd(List.nth(l, i))
返回的引用设置为1
。因为l
是一个 int 列表,然后List.nth(l, i)
returns 那个(或崩溃)的第i
个元素,它是一个 int 列表 。然后List.hd(...)
取第一个元素(或崩溃),它是 int。不是 int ref。要使此行正常工作,您需要
l : int ref list list
.但你不想这样。
i = i - 1
是一个布尔表达式,即returnstrue
ifi
等价于自身减1。这对任何整数。您可能打算从i
中减去 1 并将结果放入i
,但您不能这样做,因为i
不是可变变量,并且更新 [=74] 的运算符=]ref 被称为:=
.
如果您的问题是转换列表
val m = [ [ 1, 2, 3 ],
[ 4, 5, 6 ],
[ 7, 8, 9 ] ]
入榜
val n = [ [ 1, 2, 3 ],
[ 1, 5, 6 ],
[ 1, 8, 9 ] ]
那么一个简单的方法就是使用 List.map
:
val n = List.map (fn row => 1 :: List.drop (row, 1)) m
一种更手动的方法,在 迭代 上练习 递归 和 模式匹配 ,例如 while ... do
(只有当你有可变变量时才有效)和 部分函数 像 List.hd
和 List.nth
(可能会崩溃)可能是:
fun f [] = []
| f (row::m) = (1 :: List.drop (row, 1)) :: f m
val n = f m
如果你想要一个可变版本,请考虑 Array2
模块而不是 int list list.
这是一个 Array2
使用递归增加游标的解决方案:
fun appulate f from to =
if from > to then ()
else (f from; appulate f (from+1) to)
fun f col m =
appulate (fn row => Array2.update (m, row, col, 1))
0 (Array2.nRows m - 1)
fun show m =
Array2.appi Array2.RowMajor (fn (_, col, c) =>
print (Int.toString c ^ (if col + 1 = Array2.nCols arr then "\n" else "" )))
{base=arr,row=0,col=0,nrows=NONE,ncols=NONE};
val m' = Array2.fromList m
val n' = f 0 m'
val _ = show n'
我意识到我没有给出 while ... do
的任何示例,也没有给出 int ref 的任何集合ref
, !
和 :=
.