这个标准的ML函数给了我“未处理的异常:Match”。有人可以指出我正确的方向来解决问题吗?

时间:2018-09-22 02:13:13

标签: sml

我正在尝试编写一个名为“ select”的标准ML函数,该函数会接收一个整数列表和一个函数。传递的函数接收一个整数并返回一个布尔值(例如,fun isOdd 3-> true)。如果给定函数对该整数返回true,则该函数将遍历列表中的每个整数并将它们附加到新列表中。因此port将返回df.head() date ticker return marketcap 2004m1 A 0.02500 2.500117e+10 2004m1 B 0.04000 3.600111e+10 2004m1 C -0.01500 4.900222e+11 2004m1 D -0.02500 1.400134e+10 2004m1 E -0.04000 3.200288e+10 2004m1 F -0.01200 9.300110e+10 2004m1 G 0.03500 5.500512e+12 2004m1 H 0.04600 2.100177e+11 2004m1 I 0.00500 3.300155e+10 2004m1 J 0.00750 2.400999e+13 2004m1 K 0.02500 7.700155e+10 2004m2 A 0.03500 2.600118e+10 2004m2 B 0.02000 3.300333e+10 2004m2 C -0.00500 4.500477e+11 2004m2 D 0.01100 1.800155e+10 2004m2 E -0.02000 3.500288e+10 2004m2 F 0.01200 3.001109e+11 2004m2 G 0.04200 5.700442e+12 2004m2 H 0.01100 2.800888e+11 2004m2 I 0.01900 3.600115e+10 2004m2 J 0.00550 2.100333e+13 2004m2 K -0.01500 5.001550e+10 。 这是我得到的代码:

select [1,2,3,4,5] isOdd

2 个答案:

答案 0 :(得分:1)

recurse没有空列表的大小写,因此当您到达空列表时,它将失败。

让我们解决这个问题:

fun select (l : int list, f:int -> bool) = 
    let val newlist : int list = []
        fun recurse [] = []
          | recurse (x::xs) =
            if f(x)
                then newlist :: [x] :: recurse(xs)
            else
                newlist :: recurse(xs)
    in
        recurse l
    end

并测试:

- select ([1,2,3,4], fn x => x mod 2 <> 0);
val it = [[],[1],[],[],[3],[]] : int list list
- select ([1], fn x => true);
val it = [[],[1]] : int list list
- select ([1], fn x => false);
val it = [[]] : int list list

那不好–我们想要[1,3][1][]

函数的类型是

val select = fn : int list * (int -> bool) -> int list list

int list list结果错误;应该是int list
发生这种情况是因为recurse的结果的第一个元素是int list –空的newlist –所以结果必须是int list list

解决问题所在

fun select (l : int list, f:int -> bool) = 
    let fun recurse [] = []
          | recurse (x::xs) =
            if f x
            then x :: recurse xs
            else recurse xs 
    in
        recurse l
    end

请注意,类型约束是毫无意义的;如果删除它们,您将获得更多有用的多态函数。

答案 1 :(得分:0)

除了删除类型约束之外,继续molbdnilo对select的重写,也不需要具有内部递归功能,因为select本身很容易递归:

fun select ([], f) = []
  | select (x::xs, f) =
    if f x
    then x :: select (xs, f)
    else select (xs, f)