SML - 素数分解,构建列表错误

时间:2013-06-28 05:30:00

标签: list recursion sml prime-factoring

我正在尝试编写一个SML函数,它将所有素因子列表返回给定数字。这将最终成为另一个函数的辅助函数。

最初,bigNumber是我需要找到素数因子的数字,并且我作为除数传递的数字少于1。以下是我如何调用它来查找数字100的素因子的示例。getPrimeFactors 100 99;

我现在不太担心算法是否存在缺陷,但如果你发现任何错误,我会很乐意听。

我的主要问题是尝试将返回值作为列表传递到递归链上,然后在它们与其他列表相遇时组合这些列表。

fun getPrimeFactors bigNumber divisor = 
    if divisor > 0 then 
        if (bigNumber mod divisor) = 0 then List.concat(getPrimeFactors (bigNumber div divisor) ((bigNumber div divisor) - 1), getPrimeFactors divisor (divisor - 1))
        else [getPrimeFactors bigNumber (divisor - 1)]
    else [bigNumber];

运行这个给了我这个错误。     C:..... \ run.x86-win32.exe:致命错误 - 未捕获异常错误0     来自../ compiler / TopLevel / interact / evalloop.sml:66.19-66.27

C:\.....\commonFactors.sml:3.39-3.160 Error: operator and operand don't agree [tycon mismatch]
    operator domain: 'Z list list
    operand:         'Y * 'Y
        in expression:
            List.concat
            ((getPrimeFactors (<exp> div <exp>)) (<exp> div <exp> - 1),
             (getPrimeFactors divisor) (divisor - 1))
[Finished in 0.4s with exit code 1]

非常感谢任何帮助!

2 个答案:

答案 0 :(得分:2)

你试图在元组上调用List.concat。 List.concat的类型是

fn : 'a list list -> 'a list

也就是说,它需要一个列表列表,将所有连接在一起,然后返回结果。那是你的错误。

如果我们使用@运算符代替使用List.concat,我们会得到一个不同的错误(在您的系统上可能会略有不同):

File "test.sml", line 7, characters 14-53:
!         else [getPrimeFactors bigNumber (divisor - 1)]
!               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
! Type clash: expression of type
!   'a list
! cannot have type
!   'a
! because of circularity

此错误是因为getPrimeFactors应返回int list,但您在此处尝试将getPrimeFactors的结果填入列表中,从而获得int list list

答案 1 :(得分:0)

以防万一有人好奇这里是使用正确算法的纠正代码。由于Tayacan,能够修复List.concat错误。

fun getPrimeFactors big small = 
    if small > 1 then 
        if (big mod small) = 0 then List.concat[(getPrimeFactors (big div small) (big div small - 1)), (getPrimeFactors small (small - 1))]
        else List.concat[(getPrimeFactors big (small - 1))]
    else if big = 1 then nil
        else [big];