List 理解ML中的foldl

List 理解ML中的foldl,list,functional-programming,iterator,sml,metalanguage,List,Functional Programming,Iterator,Sml,Metalanguage,我需要编写一个函数,它接受一个字符串列表并查找列表中最大的字符串。问题是它需要使用list.foldl在列表中迭代,并且除了list.foldl的库函数中的递归调用外,不能使用递归调用 我写 fun longest_string1(xs)= case xs of [] => "" | x::xs' => List.foldl((fn (s,x) => if String.size s > String.size x then s else x) "" x,) 我

我需要编写一个函数,它接受一个字符串列表并查找列表中最大的字符串。问题是它需要使用list.foldl在列表中迭代,并且除了list.foldl的库函数中的递归调用外,不能使用递归调用

我写

fun longest_string1(xs)= 
case xs of 
[] => ""  
| x::xs' => List.foldl((fn (s,x) => if String.size s > String.size x then s else x) "" x,)
我的解释如下:

-接受xs,如果xs为空,则返回一个空字符串

-对于xs呼叫列表的第一项,否则。foldl

-foldl传入一个匿名函数,该函数检查s的长度,s应代表与列表头项相对应的累加器

-将初始累加器设置为空字符串,将初始比较值设置为高阶函数传入的初始列表的开头

但是,它不进行类型检查


我认为我的问题在于理解List.foldl函数本身以及它如何准确读取其参数。有人能澄清一下吗

因此,对于您发布的代码:

  • 空列表不需要案例。福尔德会帮你处理的。只需将xs传递给foldl而不是x
  • foldl是咖喱的,所以参数周围不应该有括号
  • 除此之外,它实际上看起来是正确的。无论如何,如果您仍然不确定foldl是如何工作的,那么这里有一个非常详细的解释;)

    好的,让我们从List.foldl开始

    val foldl : ('a * 'b -> 'b) -> 'b -> 'a list -> 'b
    
    因此,有三个参数。一个是我们将在后面讨论的函数,第二个是与返回类型相同类型的值,最后一个是列表

    我们举一个简单的例子,比如说我们有一个int的列表,我们想把所有的数字加起来。我们可以这样做:

    fun sum [] = 0
      | sum (x::xs) = x + sum xs
    
    或者,我们可以使用foldl(从现在起,我将编写foldl而不是List.foldl,因为我很懒)

    因此,我们知道列表是第三个参数。第二个应该是某种起始值,或者累加器,如果列表为空,那么它是有意义的。对于一个总数来说,那将是0

    第一个参数是一个函数,这是一个棘手的部分。类型为:

    fn : 'a * 'b -> 'b
    
    好的,那么‘a也是列表中元素的类型,所以如果这是列表中的一个项目,这是有意义的。’b是起始值和返回值的类型

    实际上,foldl使用列表中的第一个元素和累加器调用函数。然后,它用结果调用自己作为新的累加器,并调用列表的其余部分。因此,如果我们这样做:

    foldl foo 0 [1,2,3]
    

    foo (1,0)
    
    然后

    foldl foo (foo (1,0)) [2,3]
    
    等等

    对于列表求和,我们将使用以下函数:

    fn (x,acc) => x + acc
    
    因此,我们可以这样做:

    fun sum xs = foldl (fn (x,acc) => x + acc) 0 xs
    
    或者更简单

    val sum = foldl op+ 0
    
    op+
    与我前面使用的匿名函数相同)

    让我们用列表浏览一下
    [1,2,3]

    foldl op+ 0 [1,2,3]
    foldl op+ (op+ (1,0)) [2,3] -> foldl op+ 1 [2,3]
    foldl op+ (op+ (2,1)) [3]   -> foldl op+ 3 [3]
    foldl op+ (op+ (3,3)) []    -> foldl op+ 6 []
    6