我正在制作一个数独求解器,我想知道为什么sml编译器在说:
expression: int * int -> int -> int list list list
result type: int * int -> int -> int list
宣言中的
val moveandsolve = (fn arg => (fn pat => exp))
我正在尝试返回列表列表(板列表),但它告诉我它正在返回一个int列表?我没有正确使用相互递归吗?
fun solve board =
let fun fillInAndSolve (board, (row, col)) entry=
let val newbrd1 = fillin (board,(row,col),entry)
in
if(contradictionDetected newbrd1) = true
then
[]
else
let val newbrd2 =
forces newbrd1
in
if(contradictionDetected newbrd2) = true
then
[]
else
if (hasEmptyPos newbrd2) = false
then
newbrd2
else
List.map (moveandsolve board (findFirstBlank newbrd2))
(generateListOfLegals(newbrd2,findFirstBlank newbrd2))
end
end
in List.map (fillInAndSolve(board, findFirstBlank board))
(generateListOfLegals(board, findFirstBlank(board)))
end
and moveandsolve board (row, col) label =
solve (fillin(board, (row,col), label ));
答案 0 :(得分:1)
我没有正确使用相互递归吗?
没有
虽然您没有指定具有此类型的功能(您提供多个),但您省略了部分:generateListOfLegals
,contradictionDetected
,{{1} },forces
,hasEmptyPos
,fillin
,导致程序无法编译。假设它们都存在并且不对类型推断添加约束,则会出现以下类型错误:
findFirstBlank
循环在解决类型时是一种冲突。一个更简单的例子可能就是这个函数:
! solve (fillin(board, (row,col), label ));<EOF>
! ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
! Type clash: expression of type
! 'a list list
! cannot have type
! 'a
! because of circularity
如果有效,那么fun f x = f [x];
会导致递归,直到内存不足为止。但它没有通过类型检查:如果输入类型是&#39; a ,那么输出类型必须是&#39;列表 。但是输入类型必须是&#39;列表,输出类型&#39;列表,依此类推:
f x = f [x] = f [[x]] = f [[[x]]] = ...
因此,您的功能似乎将输入列表列表分解为&#39; a 并将其自身(间接)提供给输入。 所以:尝试并查看函数在所有情况下返回的内容,并查看这些表达式是否都具有相同的类型。我怀疑! Type clash: expression of type
! 'a list
! cannot have type
! 'a
! because of circularity
可能没有正确的返回类型,但这纯粹是猜测。