Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/fsharp/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
帮我解释一下这个F#递归示例程序_F#_Recursion - Fatal编程技术网

帮我解释一下这个F#递归示例程序

帮我解释一下这个F#递归示例程序,f#,recursion,F#,Recursion,这个例子来自Thomas Petricek的“面向现实世界的函数式编程” 我不理解第二个分支中的模式匹配:f rem hd。 有人能帮我吗?它调用函数f(参数之一),给出递归调用的结果和下一项 rem是余数,或者在本例中是剩余值的结果 hd是下一项,如模式匹配的|hd::tl->部分所示 实际上,这个聚合函数包含一个函数、一个起点和一个列表。表示示例行的一种方法是: let rec aggregateList (f:int->int->int) init list = ma

这个例子来自Thomas Petricek的“面向现实世界的函数式编程”

我不理解第二个分支中的模式匹配:f rem hd。 有人能帮我吗?

它调用函数f(参数之一),给出递归调用的结果和下一项

rem
是余数,或者在本例中是剩余值的结果

hd
是下一项,如模式匹配的
|hd::tl->
部分所示

实际上,这个聚合函数包含一个函数、一个起点和一个列表。表示示例行的一种方法是:

let rec aggregateList (f:int->int->int) init list = 
    match list with
    | [] -> init
    | hd::tl -> 
        let rem = aggregateList f init tl
        f rem hd

let add a b = a + b
let mul a b = a * b

//to use in F# Interactive:
//aggregateList add 0 [1..5];;
它调用函数f(其中一个参数),给出递归调用的结果和下一项

rem
是余数,或者在本例中是剩余值的结果

hd
是下一项,如模式匹配的
|hd::tl->
部分所示

实际上,这个聚合函数包含一个函数、一个起点和一个列表。表示示例行的一种方法是:

let rec aggregateList (f:int->int->int) init list = 
    match list with
    | [] -> init
    | hd::tl -> 
        let rem = aggregateList f init tl
        f rem hd

let add a b = a + b
let mul a b = a * b

//to use in F# Interactive:
//aggregateList add 0 [1..5];;

让我们先分解一下
aggregateList
函数声明。该函数采用三个参数:

  • 一个名为f的函数,它接受两个
    int
    s并返回第三个
    int
  • 开始聚合时使用的初始值
  • 值的列表
  • 然后,该函数将与提供给它的列表匹配,该列表具有以下两种可能性之一:

  • 列表为空,在这种情况下,它返回
    init
    的值
  • 列表不是空的,在这种情况下,它获取第一项并将其分配给
    hd
    (或head),其余部分并将其分配给
    tl
    (或tail)。然后它执行递归调用
    aggregateList f init tl
    。当返回时,它获取结果并将其分配给
    rem
    。然后它在
    rem
    hd
    上调用
    f
  • 正如其他人所指出的,这与


    当然,要小心正确选择
    init
    值,因为如果执行
    aggregateList mul 0 somelist
    无论您提供什么列表,您都只会得到
    0

    让我们先分解
    聚合列表
    函数声明。该函数采用三个参数:

  • 一个名为f的函数,它接受两个
    int
    s并返回第三个
    int
  • 开始聚合时使用的初始值
  • 值的列表
  • 然后,该函数将与提供给它的列表匹配,该列表具有以下两种可能性之一:

  • 列表为空,在这种情况下,它返回
    init
    的值
  • 列表不是空的,在这种情况下,它获取第一项并将其分配给
    hd
    (或head),其余部分并将其分配给
    tl
    (或tail)。然后它执行递归调用
    aggregateList f init tl
    。当返回时,它获取结果并将其分配给
    rem
    。然后它在
    rem
    hd
    上调用
    f
  • 正如其他人所指出的,这与


    当然,要小心正确选择
    init
    值,因为如果执行
    aggregateList mul 0 somelist
    无论您提供什么列表,您都将得到
    0

    为了好玩,让我们做一些
    printf
    风格的调试:

    (1 + (2 + (3 + (4 + (5 + 0)))))
    
    看起来该函数相当于列表。foldBack(或其他语言中的
    fold_right
    ):它从右向左遍历列表中的每个项目,并调用其上的函数
    f

    让我们以几种不同的方式重新编写函数:

    > aggregateList (fun acc x -> printf "%i " x; acc + x) 0 [1..10];;
    10 9 8 7 6 5 4 3 2 1 val it : int = 55
    

    我不明白在第二分店里 模式匹配:f rem hd。能够 谁来帮帮我

    那么让我们从我们已经知道的F函数开始:

    • f
      是一个类型为
      int->int->int
      的函数。传递函数时,就好像它们是int或string之类的任何其他变量一样
    • 通过传递以空格分隔的参数列表来调用函数
      f rem hd
      使用两个参数调用函数
      f
      rem
      hd
    • 函数中计算的最后一个表达式被视为函数的返回值
    回到原来的函数:

    let sum = foldBack (+) 0 [1..10] // returns 55
    let sumOfSquares = foldBack (fun acc x -> acc + x * x) 0 [1..10];; // 385
    
    在第1行中,我们使用
    tl
    反复调用
    aggregateList
    。由于列表越来越小,我们最终会遇到nil情况,它返回
    init

    在第2行中,
    f rem hd
    是函数的返回值。但是,由于我们在到达列表末尾时沿着堆栈递归,所以我们将在沿着堆栈跟踪返回时,为每个元素调用一个函数(按从右到左的顺序)

    给定
    aggregateList(+)0[1..10]
    ,nil案例返回
    0
    ,因此我们调用:

    • 返回值=f rem hd=f 0 10=0+10=10
    • 返回值=f rem hd=f 10 9=9+10=19
    • 返回值=f rem hd=f 19 8=19+8=27
    • 返回值=f rem hd=f 27 7=27+7=34
    • 返回值=f rem hd=f 34 6=34+6=40
    • 返回值=f rem hd=f 40 5=40+5=45
    • 返回值=f rem hd=f 45 4=45+4=49
    • 返回值=f rem hd=f 49 3=49+3=52
    • 返回值=f rem hd=f 52 2=52+2=54
    • 返回值=f rem hd=f 54 1=54+1=55
    列表中没有更多项,因此整个函数返回
    55

    可以想象,
    aggregateList
    中的嵌套调用对长度
    n
    的列表进行如下计算:

    f(f(f(f(f(f(f(f)init hdn)hdn-1)hdn-2)hdn-3)…hd2)hd1)hd0仅用于f
    let rec aggregateList (f:int->int->int) init list = 
        match list with
        | [] -> init
        | hd::tl -> 
            let rem = aggregateList f init tl   // 1
            f rem hd                            // 2