将列表分区为等价类

时间:2016-11-13 18:17:17

标签: functional-programming sml smlnj

我正在尝试在SML中编写一个函数,当给出一般元素列表时,将其元素重新排序为等价类并返回这些类的列表(类型"列表列表)。 保留类中的元素的顺序与原始列表中的顺序相同。 给定函数定义元素的等价性,如果元素相等则返回true,否则返回false。 我似乎无法控制解决方案。

fun sample x y = x = y

必填类型: fn :('' a - >'' a - > bool) - > ''列表 - > ''列表

非常感谢您的帮助。

辅助函数无法正常工作,我想用它来查看给定元素是否属于任何类并将其相应放入或创建一个包含它的新子列表。

fun srt listoflists func new = 
        case listoflists of [] => [[]]
         |  a::b => if func (new, hd a) = true then (new::a)::b
                    else if func (new, hd a) = false then a::(srt b func new) else [new]::a::b

样本函数在除以11时检查两个元素的等价性。

测试并非全部有效,它不会在新课程中添加17个。

 srt [[7,7,7],[5,5,5],[11,11,11],[13,13,13]] eq 7;
val it = [[7,7,7,7],[5,5,5],[11,11,11],[13,13,13]] : int list list
- srt [[7,7,7],[5,5,5],[11,11,11],[13,13,13]] eq 5;
val it = [[7,7,7],[5,5,5,5],[11,11,11],[13,13,13]] : int list list
- srt [[7,7,7],[5,5,5],[11,11,11],[13,13,13]] eq 11;
val it = [[7,7,7],[5,5,5],[11,11,11,11],[13,13,13]] : int list list
- srt [[7,7,7],[5,5,5],[11,11,11],[13,13,13]] eq 13;
val it = [[7,7,7],[5,5,5],[11,11,11],[13,13,13,13]] : int list list
- srt [[7,7,7],[5,5,5],[11,11,11],[13,13,13]] eq 17;
val it = [[7,7,7],[5,5,5],[11,11,11],[13,13,13],[]] : int list list
- srt [[7,7,7],[5,5,5],[11,11,11],[13,13,13],[111,111,111]] eq 111;
val it = [[7,7,7],[5,5,5],[11,11,11],[13,13,13],[111,111,111,111]]

如何纠正这个问题,并且一旦这个帮助函数工作,如何将它完全包含在所需的主函数中。

非常感谢。

1 个答案:

答案 0 :(得分:1)

您的示例代码似乎越来越接近,但有几个问题

1)基本情况是应添加new的位置,因此在这种情况下,您应该返回值[[new]]而不是[[]]

2)您的问题描述表明func属于''a -> ''a -> bool类型,但srt的代码似乎假设它属于(''a * ''a) -> bool类型。而不是像func (new, hd a)这样的子表达式,您需要func new (hd a)(请注意括号位置)。

3)如果func返回bool,则将输出与true进行比较是不必要的冗长,而不是if func new (hd a) = true then ...只需if func new (hd a) then ...

4)由于您在基础案例中添加[new],因此您的第二个条款不必要地冗长。我认为没有理由拥有任何嵌套的 if表达式。

由于这似乎是家庭作业,我不想说更多。一旦你使帮助程序正常工作,使用它(在递归情况下)整个函数应该是相当简单的。请注意,如果您希望避免在最终返回值中最终映射(a @ [new])::b,则可以使用(new::a)::b而不是rev@::O(n)而不是O(1)),但是对于小例子来说,它确实无关紧要,甚至可能稍微好一些它将避免扭转列表的最后一步。