如何在 Haskell 中使用数据结构?

sio*_*son 1 haskell

我被分配制作一个包含学生数组(应该包含学生数据)的简单程序,我知道 Haskell 不是面向对象的编程语言,我正在寻找一种构建学生数据的方法,我想到了嵌套元组进入数组,然后进入学生数组,但问题是我有不同的数据类型(String,int ...等),所以元组不起作用,我还在Stack Overflow上找到了这个答案,它创建了一个新的数据类型根据我的理解,但我未能实现它,这是我尝试过的:

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])
Run Code Online (Sandbox Code Playgroud)

似乎什么都不起作用。

Tho*_*ook 5

不确定你想做什么,因为这个问题非常广泛。但是,这里有一些示例可能有助于理解......

定义您的学生数据类型:

data Student = Student {
   name :: String,
   grade :: Int
}
Run Code Online (Sandbox Code Playgroud)

您想要一份默认学生名单吗?像这样创建它:

initializeStudents :: Int -> [Student]
initializeStudents count = map (\_ -> Student "" 0) [1..count]
Run Code Online (Sandbox Code Playgroud)

您还可以从磁盘读取学生信息,这需要使用 IO monad,因此超出了这些基础知识的范围。

您想对学生列表的成绩求和吗?像这样做:

sumGrades :: [Student] -> Int
sumGrades students = sum $ map grade students
Run Code Online (Sandbox Code Playgroud)

您想获得学生列表的平均成绩吗?像这样做:

averageGrades :: [Student] -> Double
averageGrades students = fromIntegral (sumGrades students) / fromIntegral (length students)
Run Code Online (Sandbox Code Playgroud)

你想在 IO monad 中打印学生的平均成绩吗?你可以这样做:

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

  let averageGrade = averageGrades students

  print averageGrade
Run Code Online (Sandbox Code Playgroud)

您是否想要存根实际学生列表而不是默认学生列表,然后打印存根列表的平均成绩?像这样做:

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

  let averageGrade = averageGrades students

  print averageGrade
Run Code Online (Sandbox Code Playgroud)

为了将所有这些结合在一起,一个简单的程序询问用户想要输入多少学生记录,然后要求他们输入每条记录,最后打印学生的平均成绩:

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
Run Code Online (Sandbox Code Playgroud)