Моя задача состоит в том, чтобы создать меню с четырьмя вариантами: - добавить новых студентов - показать всех студентов, - удалить студентов по ID - закрыть программу. Я использовал Hashmap для этой проблемы, но проблема в том, что я понятия не имею, как отобразить текущий список созданных студентов.
Мой код представлен ниже:
{module StudentApp where
import Data.HashMap.Strict
import System.Exit (exitSuccess)
data Student = Student {name::String, age::Int, id::String}
deriving (Show, Eq, Read)
type Students = HashMap String Student
addStudent:: Students -> IO(Students)
addStudent students = do
putStrLn ("Student Name")
name<-getLine
putStrLn("Student Age")
age<-readLn :: IO Int
putStrLn("Student ID")
id<-getLine
let s = Student name age id
let updatedStudents = insert id s students
return updatedStudents
--showStudent:: Students -> IO (Students)
deleteStudent:: Students -> IO (Students)
deleteStudent students = do
putStrLn ("Give student ID to remove")
id<-getLine
let updatedStudents = delete id students
return updatedStudents
menu :: Students -> IO ()
menu students = do
putStrLn ("1. Add new student")
putStrLn ("2. Show all students")
putStrLn ("3. Delete Student by ID")
putStrLn ("4. Exit program")
choice<-getLine
updatedStudents <- case choice of
"1" -> addStudent students
--"2" -> showstudent
"3" -> deleteStudent students
"4" -> exitSuccess --System.Exit.exitSuccess (zwraca typ IO students)
menu updatedStudents
main :: IO ()
main = do
let students = empty :: Students
menu students
}
Всего 1 ответ
Учитывая, что ключи k
и значения v
являются экземплярами Show
, HashMap
является экземпляром Show
. Действительно, в исходном коде мы видим :
instance (Show k, Show v) => Show (HashMap k v) where showsPrec d m = showParen (d > 10) $ showString "fromList " . shows (toList m)
Таким образом, мы можем использовать print :: Show a => a -> IO ()
здесь, чтобы напечатать содержимое HashMap
. Подобно:
Prelude Data.HashMap.Strict> print (fromList [("id001", Student "Foo" 21 "id001"), ("id003", Student "Bar" 19 "id003")])
fromList [("id003",Student {name = "Bar", age = 19, id = "id003"}),("id001",Student {name = "Foo", age = 21, id = "id001"})]
Таким образом, здесь print
содержит в качестве аргумента HashMap String Student
нами HashMap String Student
, и это будет печатать содержимое словаря.
Вы также можете использовать ToList :: HashMap kv -> [(k, v)]
чтобы преобразовать ваш HashMap kv
в список кортежей ключ-значение, а затем показать значения с некоторыми дополнительными функциями.
Например, мы можем напечатать каждое значение (здесь Student
) в отдельной строке с помощью:
mapM_ (print . snd) (toList myhashmap)
В своем меню вы можете написать:
menu :: Students -> IO ()
menu students = do
putStrLn "1. Add new student"
putStrLn "2. Show all students"
putStrLn "3. Delete Student by ID"
putStrLn "4. Exit program"
choice <- getLine
updatedStudents <- case choice of
"1" -> addStudent students
--"2" -> showstudent
"3" -> deleteStudent students
"4" -> exitSuccess --System.Exit.exitSuccess (zwraca typ IO students)
print updatedStudents
menu updatedStudents
Совет : в вашей текущей программе вы постоянно используете блоки
do
. Обычно в программе на Haskell вы пишете логику, не требующуюIO
,State
и т. Д., Отдельно в функциях, выполняющих небольшое количество задач.