How to work with data structures in Haskell? [closed]

回眸只為那壹抹淺笑 提交于 2020-02-08 10:05:43

问题


I'm assigned to make a simple program that contains a students array (which should contain students data), I know that Haskell is not an OO programming language, I was looking for a way for structuring my student data, I thought of nesting tuples into arrays and then into the students array, but the problem is that I have different data types (String, int ...etc.) so tuples doesn't work, I also found this answer on Stack Overflow that creates a new data type from what I understood but I failed to implement it, here is what I have tried:

data Student =
  Student { name :: Char
   , surename :: Char 
   , moy1 :: Int
   , coef1 :: Int
   , moy2 :: Int
   , coef2 :: Int
   , moy3 :: Int
   , coef3 :: Int
   , mg :: Int 
   }

main :: IO ()
main = do 
 putStrLn "Enter students data:"
 students <- initializeStudents 10
 putStrLn "calculate student average ?"
 if(reponse == "yes") then putStrLn "Enter the student firstname"
                           first <- getLine
                           // search on the array student for the student with firstname == first 
                           // then 
                           // putStrLn $ "student average is " ++  calculateData student
 else putStrLn "Okey"

 initializeStudents :: Int -> [Student]
 initializeStudents count = map (\_ -> Student "" "" 0 0 0 0 0 0 0 ) [1..count]


calculateData :: student -> Int
calculateData student = (a +  b +  c) / d
                        where a = student.moy1 * student.coef1
                              b = student.moy2 * student.coef2
                              c = student.moy3 * student.coef3
                              d = student.coef1 + student.coef2 + student.coef3


saisirDonnees:: Int -> [student] -> IO [student]
saisirDonnees 0 studentsSoFar = return studentsSoFar
saisirDonnees n studentsSoFar = do
  student <- getLine
  saisirDonnees(n-1) (studentsSoFar ++ [student])

Nothing seems to work.


回答1:


Not sure what you want to do as the question is very broad. But, here are some examples that may help understanding...

Define your Student data type:

data Student = Student {
   name :: String,
   grade :: Int
}

You want a list of default students? Create it like this:

initializeStudents :: Int -> [Student]
initializeStudents count = map (\_ -> Student "" 0) [1..count]

You could also read the students in from disk, that would require use of IO monad so is beyond scope of these basics.

You want to sum the grades of a list of students? Do it like this:

sumGrades :: [Student] -> Int
sumGrades students = sum $ map grade students

You want to get the average grade of a list of students? Do it like this:

averageGrades :: [Student] -> Double
averageGrades students = fromIntegral (sumGrades students) / fromIntegral (length students)

You want to print the average grade of students in the IO monad? You can do so like:

main :: IO ()
main = do
  let students = initializeStudents 10

  let averageGrade = averageGrades students

  print averageGrade

Do you want to stub out a list of actual students instead of the default ones and then print the average grade of the stubbed list? Do it like this:

main :: IO ()
main = do
  let students = [Student "Tim" 10, Student "Bob" 25, Student "Alice" 19]

  let averageGrade = averageGrades students

  print averageGrade

To bring this all together, a simple program that asks the user how many student records they want to input, then asks them to input each record and then finally prints the average grade of the students:

data Student = Student {
    name :: String,
    grade :: Int
} deriving (Read, Show)

sumGrades :: [Student] -> Int
sumGrades students = sum $ map grade students

averageGrades :: [Student] -> Double
averageGrades students = fromIntegral (sumGrades students) / fromIntegral (length students)

readStudentLines :: Int -> IO [Student]
readStudentLines 0 = return []
readStudentLines count = do
  current <- fmap (\student -> read student :: Student) getLine
  theRest <- readStudentLines (count -1)
  return $ current : theRest

main :: IO ()
main = do
  putStrLn "How many student records do you wish to enter? (Must be int)"

  numberStudents <- readLn :: IO Int

  putStrLn $ "Start entering your " ++ show numberStudents ++ " student records"
  putStrLn "(Note, they must be in the format: Student {name, grade} )"
  putStrLn $ "For instance: " ++ show (Student "Tom" 10)

  students <- readStudentLines numberStudents

  let averageGrade = averageGrades students

  print averageGrade


来源:https://stackoverflow.com/questions/59931560/how-to-work-with-data-structures-in-haskell

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!