Как отобразить hashmap в Haskell

Моя задача состоит в том, чтобы создать меню с четырьмя вариантами: - добавить новых студентов - показать всех студентов, - удалить студентов по 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 и т. Д., Отдельно в функциях, выполняющих небольшое количество задач.


Есть идеи?

10000