我正在寻找不使用递归的解决方案。我有 3 个数据,例如:
names = ["Alice", "Bob", "Charlie", "David"]
-- their grades:
grades :: [[Int]]
grades = [[3, 2], [4, 6], [2, 3], [1, 4]]
-- And the weights for a total note
weights :: [Float]
weights = [0.75, 0.25]
这应理解如下:
Alice's grades: 3 and 2 -- The grade 3 weighted with 75% and the grade 2 with 25%
Bob's grades: 4 and 6 -- The grade 4 weighted with 75% and the grade 6 with 25%
Charlie's grades: 2 and 3 -- The grade 2 weighted with 75% and the grade 3 with 25%
David's grades: 1 and 4 -- The grade 1 weighted with 75% and the grade 4 with 25%
我写了一个函数来计算一个学生的averageGrade
:
averageGrade :: [Float] -> [Int] -> Float
我必须根据此类型完成一个功能:
allStudents :: [String] -> [[Int]] -> [Float] -> [(String, Float)]
此函数应给出每个人的元组及其平均成绩,例如:
[("Alice", 2.75), ("Bob", 4.5), etc....]
计算由averageGrade (weights) ([Specific Grades])
进行,例如
averageGrade (weights) ([3,2])
如果我想为爱丽丝计算它。
如何在不通过head
和tail
遍历列表的情况下迭代列表(因为不允许递归)?
所以你想要
allStudents :: [String] -> [[Int]] -> [Float] -> [(String, Float)]
这与
allStudents2 :: [String] -> [Float] -> [[Int]] -> [(String, Float)]
而你有
averageGrade :: [Float] -> [Int] -> Float
这样
averageGrade (weights :: [Float]) :: [Int] -> Float
自从
map (foo :: a -> b )
:: [ a ] -> [ b ]
我们有
map (averageGrade weights) :: [[Int]] -> [Float]
和
map (averageGrade weights) (grades :: [[Int]]) :: [Float]
拼图最后缺失的部分是
_ :: [ c ] -> [ b ] -> [( c , b )]
这样
_ (names :: [String]) :: [ b ] -> [(String, b )]
如果你被禁止使用递归,这意味着你应该使用一些标准函数,如foldl
、foldr
、map
、zip
等。
由于您具有处理学生成绩averageGrade
函数,因此您可以使用如下map
处理此类列表:
map (averageGrade weights) grades
它将averageGrade weights
函数一一应用于列表的每个元素,并返回结果列表,即每个学生的平均成绩列表。
所以现在,当你处理所有学生的数据时,你所需要的只是将每个学生的名字与适当的平均成绩配对。您可以使用zip
函数来实现:
allStudents :: [String] -> [[Int]] -> [Float] -> [(String, Float)]
allStudents names grades weights = zip names $ map (averageGrade weights) grades
您可以在此处进行测试:https://repl.it/@Yuri12358/so-zip