Reputation: 109
I have to a data Student and a type Class:
data Student = Student {nome :: String
, stdNumber :: Int
, approvedClass :: Int
, failedClass :: Int
}
type Class = [Student]
and I'm trying to add to All the students in Class more approvednumber and failed of a Student but i'm don't know how to do it . I already have this:
getStudent :: Class-> String -> Maybe Student
getStudent [] _ = Nothing
getStudent (student:xs) s
| name student == s = Just student
| otherwise = getStudent xs s
addClasses :: Student-> Int -> Int -> Student
addClasses student aC fC =
student { approvedClass = approvedClass student + aC
, failedClass = failedClass student + fC
}
addClassesToAllStd :: Class-> [(String, Int, Int)] -> Class
addClassesToAllStd cl [] = cl
addClassesToAllStd [] _ = []
addClassesToAllStd ((Student name _ approvedClass failedClass):xs) ((n,aC,fC):ys) = [(Student _ _ approvedClass+aC failedClas+fC)] ++ addClassesToAllStd xs ys
But I don't know how to check if i'm adding to the right student? And I don't understand why this doesn't work (even without checking if i'm adding to the right studdent)?
Here's an exempla how it's supposed to work:
>french1 = addClassesToAllStd french [("Emma",5,1),
("Max",3,3), ("Carol",4,2)]
> carol = getStudent french1 "Carol"
> approvedClass carol
4
> failedClass carol
4
> max = getStudent french "Max"
> approvedClass max
3
> failedClass max
3
and french was french = [("Emma",0,0),("Max",0,0), ("Carol",0,0)]
Upvotes: 0
Views: 66
Reputation: 63
First thing is you cannot just omit values and leave _
. _
is a placeholder that you can leave during development, that shows you some inferred type info that can help you understand what you can replace it with. So, at first let's fill the _
's and fix some syntactical errors:
data Student = Student { name :: String
, stdNumber :: Int
, approvedClass :: Int
, failedClass :: Int
} deriving (Show)
type Class = [Student]
getStudent :: Class -> String -> Maybe Student
getStudent [] _ = Nothing
getStudent (student:xs) s
| name student == s = Just student
| otherwise = getStudent xs s
addClasses :: Student -> Int -> Int -> Student
addClasses student aC fC =
student { approvedClass = approvedClass student + aC
, failedClass = failedClass student + fC
}
addClassesToAllStd :: Class -> [(String, Int, Int)] -> Class
addClassesToAllStd cl [] = cl
addClassesToAllStd [] _ = []
addClassesToAllStd ((Student name num approvedClass failedClass):xs) ((n, aC, fC):ys) =
Student name num (approvedClass + aC) (failedClass + fC) : addClassesToAllStd xs ys
Now, this works, but only if you provide [(String, Int, Int)]
in the same order as your students. To fix that we have to do a pass through [(String, Int, Int)]
for every student, finding tuples with specified string and increasing approvdedClass
and failedClass
values:
addClassesToAllStd :: Class -> [(String, Int, Int)] -> Class
addClassesToAllStd cl [] = cl
addClassesToAllStd [] _ = []
addClassesToAllStd (x:xs) ys = x':addClassesToAllStd xs ys
where
x' = foldr updateStudent x ys
updateStudent :: (String, Int, Int) -> Student -> Student
updateStudent (name', ac', fc') s@Student { name = name, approvedClass = ac, failedClass = fc }
| name == name' = s { approvedClass = ac + ac', failedClass = fc + fc' }
| otherwise = s
We also could do exactly the opposite: iterate through [(String, Int, Int)]
and on each iteration iterate through students list, finding the matching one and increasing their approvedClass
and failedClass
values.
Upvotes: 2