f # как получить доступ к данным из другой функции? - PullRequest
0 голосов
/ 26 октября 2018

У меня проблемы с доступом к значению из другой функции в диафрагме.Ниже приведен мой код: я беру пользовательский ввод имени студента и 3 экзаменационных баллов, вычисляю их средние значения и сохраняю их в переменной «let Среднее» функции InputStudents.Теперь я пытаюсь получить доступ к этому значению в другой функции 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 голосов
/ 26 октября 2018

Это невозможно.

Вы не можете получить доступ к внутренним вычислениям из другой функции. Что вам нужно сделать, это вернуть значения, которые вам нужно использовать снаружи.

В вашем случае ваша функция 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 ->
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...