f#如何从另一个函数访问数据?

时间:2018-10-26 13:38:52

标签: f#

我无法从f Sharp中的另一个函数访问值。下面是我的代码,我让用户输入一个学生姓名和3个考试成绩并计算他们的平均值,然后将其保存在InputStudents函数的变量“ let average”中。现在,我试图在另一个函数PringtAverages中访问该值,如下所示,但无法编译。我需要帮助来解决此问题。感谢您能提供帮助。谢谢。

let rec InputStudents students =
    let line = System.Console.ReadLine()
    match line with
    | "#" -> (List.rev students)
    |  _  -> 
    let data = line.Split ' '
    //Getting the student name at data.[0], and getting the 3 exam 
    //scores in data.[1]..[3].
    let student = (data.[0], [int(data.[1]); int(data.[2]); int(data.[3])])
    //calculating the average by for the 3 exam scores
    let average = (data.[0], [(float(data.[1]) + float(data.[2]) + float(data.[3]))/3.0])
    InputStudents (student:: students) 

 //Function below I am trying to get the above-calculated averages and print
let rec PrintAverages L = 
    match L with
    | []      -> ()   
    | e::rest -> 
           let avg = InputStudents[]
           printfn "%A: %A" "netid" avg.average //Here I am trying to print 
                              //the average calculated in the function 
                             //InputStudents[] above
           PrintAverages rest

1 个答案:

答案 0 :(得分:1)

那是不可能的。

您不能从其他功能访问内部计算。您需要做的是返回需要在外部使用的值。

对于您而言,函数InputStudents具有以下签名:

(string * int list) list -> (string * int list) list

这意味着它将返回一个包含每个学生姓名和注释的列表。 average是经过计算的,但随后丢失了,因为没有在任何地方使用它。如果希望能够在其他函数中打印它,则需要将其作为返回值的一部分包括在内:

         ...
         let name    =        data.[0]
         let scores  = [float data.[1]
                        float data.[2]
                        float data.[3] ]
         //calculating the average by for the 3 exam scores
         let average = List.average scores
         InputStudents ((name, scores, average) :: students)

现在签名是这个:

(string * float list * float) list -> (string * float list * float) list

表明它为每个学生返回一个元组,包括名称,注释和平均值。


现在让我们解决PrintAverages函数。

该函数有一个问题:它调用InputStudents并以递归方式调用自身。您要做的是先调用InputStudents,然后将结果传递给PrintAverages

InputStudents [] |> PrintAverages

也可以在您的match语句中,打开要接收的元组的包装。现在,您有了e::rest,它为您提供了一个元素,并为列表提供了其余元素。该元素的类型为string * float list * float,您可以像这样解包:

let name, notes, average = e

或直接在match语句中

match L with
| [] -> ()
| (name, notes, average) :: rest ->