SML-在列表中查找元素时出错
我是SML的新手。我写了一个函数,它以2 int和一个元组列表作为输入SML-在列表中查找元素时出错,sml,Sml,我是SML的新手。我写了一个函数,它以2 int和一个元组列表作为输入 fun move(x,y,mylist:(int * int)list): NOxNO = let val counter = ref y-1 in if y=1 then (x,y) else ( while !counter > 0 do ( if List.exists (fn s => s = (x,!counter)
fun move(x,y,mylist:(int * int)list): NOxNO =
let
val counter = ref y-1
in
if y=1 then (x,y)
else (
while !counter > 0 do (
if List.exists (fn s => s = (x,!counter)) mylist
then counter := !counter - 1
else break
);
if !counter = 0 then (x,y) else (x,y-1)
)
end
我可能有语法错误,因为我是初学者。函数试图做的是:它将检查列表以查找第一个元素为x,第二个元素从1到y-1的所有元组(元组如下:(x,1)(x,2)…(x,y-1)),如果列表中存在所有元组,它将返回(x,y)else(x,y-1)。我用了一个while循环和一个计数器。计数器首先设置为y-1,在while循环中,如果找到(x,计数器),计数器的值将减小。最后,如果counter=0,则表示我们找到了所有元组。运行程序后,我遇到以下错误:
Caught Error ../compiler/TopLevel/interact/evalloop.sml:296.17-296.20
../compiler/TopLevel/interact/evalloop.sml:44.55
../compiler/TopLevel/interact/evalloop.sml:66.19-66.27
怎么了?在ML中没有
中断
。您可能只想在那里编写()
。此外,您还需要对第3行中的ref
参数进行排列。以下是一些反馈:
break
不存在。但是如果使用()
,则循环不会在y>1
时终止,谓词的计算结果为false。您可能希望通过设置计数器:=0
或计数器:=-1
来“中断”,这取决于您希望后续如果!计数器=0…
要执行的操作ref y-1
给出了以下类型的错误:
! Toplevel input:
! val r = ref y-1;
! ^
! Type clash: expression of type
! int
! cannot have type
! int ref
这是因为函数应用程序(ref y
)绑定比中缀运算符(y-1
)更紧密。您的意思是ref(y-1)
,因为您不能从引用中减去1val test1 = move (1,1,[])
但这是一个奇怪的基本情况,不由循环处理。如果我稍微改变一下数字
val test2 = move (5,6,[])
然后它返回(5,6)
或(5,5)
,具体取决于您将分解为什么
(* verticalPointsExist (x, y, ps) checks that
* (x,1), (x,2), ..., (x,y-1) are all in ps. *)
fun verticalPointsExist (_, 0, _) = true
| verticalPointsExist (x, y, ps) = List.exists (fn p => (x,y) = p) ps
andalso verticalPointsExist (x, y - 1, ps)
fun move (x, y, ps) =
if verticalPointsExist (x, y, ps) then (x,y) else (x,y-1)
我所作的考虑:
- 使用递归而不是迭代
- 将检查部分拆分为一个助手函数,这样
就不会做两件事move
- 给函数起个好名字,这样代码读起来就更容易了。因为我不知道这个领域,我真的在猜测
是否是某种垂直维度,所以可能还有更好的名字。(y
?verticalPathClear
?)也许更通用的函数会有更好的名称,例如,取两个点并看到它们之间的直线清晰的函数verticalPathClear