one user
one user

Reputation: 109

why my attempt to add to the third and fourth element of a tuple in a list dont work?

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

Answers (1)

Daniil Kolesnichenko
Daniil Kolesnichenko

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

Related Questions