
Hola! Hallo! I made my first program to understand lists and something about datat types. I have some question about the following code... * import* Data.List *data* Student = Student { id :: Int, nombre :: String } *deriving* (*Show*, *Eq*) main :: IO ()main = *do* putStrLn "---\nStudent Magnament Program\n---" loop [] ashow :: [Student] -> IO ()ashow [] = putStrLn "Empty list"ashow [x] = putStrLn $ show xashow (x:xs)= *do* putStrLn $ show x ashow xs aadd :: [Student] -> IO ()aadd xs = *do* putStrLn "Enter the id" id <- getLine putStrLn "Enter name" name <- getLine loop $ (Student (read id) (read name) ) : xs aremove :: [Student] -> IO ()aremove xs = *do* putStrLn "Enter the id" id <- getLine putStrLn "Enter name" name <- getLine loop $ delete (Student (read id) (read name) ) xs loop :: [Student] -> IO ()loop xs = *do* putStr $ "\n-------\nSelect an option\n" ++ "1) Add student\n" ++ "2) Remove student\n" ++ "3) Show all students\n" ++ "4) Exit\n" ++ "\t Your option: " option <- getLine putStrLn "\n------" *case* read option *of* 1 -> aadd xs 2 -> aremove xs 3 -> *do* ashow xs loop xs 4 -> putStrLn "God bye!" My question are: - When i ask for the data fof a student i repeat the code, cause i have to use fuctions using IO (), cuase i have to put something in the screen. Therefore i cant have a fuction that only return a Student. - loop $ (Student $ read id $ read name), is wrong why? - i think that there are best way to achive that i have done. Or is ok for a begginer that doesn't know functors or monads. Sorry for my bad english, i am Argentinean. Thanks in advance.

Hi, well you're using the IO Monad all over the place. Instead I suggest using it only in certain places (like main) and keep the functions pure in general. One way to improve this might be to start from the inside and first think about what functions you need and then what the types should look like. For example you need a function to add a student to the list, the type of pure function which does that looks like this: *aadd :: [Student] -> Student -> [Student]* Then implement this function and think from the outside: Given some user input, how can I create a student? Take a look at this[1] page.. you'll find a suggestion on how to improve your *ashow* function there. *loop $ (Student $ read id $ read name), is wrong why?* That operator you are using three times there basically says: "Evaluate the right thing first", so what you end up with after *read name* has been evaluated is *read id (read name)*. Once you understand that, you'll also find that the braces are unnecessary (though not wrong). If you want to avoid the IO Monad in general then I suggest you "test" your program with GHCI. I'm sure you'll also find examples for basic input-dialog haskell programs in either *Learn You a Haskell[2] for Great Good* or *Real World Haskell* [3]. 1: http://learnyouahaskell.com/types-and-typeclasses 2: http://learnyouahaskell.com/ 3: http://book.realworldhaskell.org/ Cheers, Reto On Sun, Dec 2, 2012 at 1:43 PM, Ezequiel Hernan Di Giorgi < hernan.digiorgi@gmail.com> wrote:
Hola! Hallo! I made my first program to understand lists and something about datat types. I have some question about the following code...
*
import* Data.List *data* Student = Student { id :: Int, nombre :: String } *deriving* (*Show*, *Eq*) main :: IO ()main = *do* putStrLn "---\nStudent Magnament Program\n---" loop [] ashow :: [Student] -> IO ()ashow [] = putStrLn "Empty list"ashow [x] = putStrLn $ show xashow (x:xs)= *do* putStrLn $ show x ashow xs aadd :: [Student] -> IO ()aadd xs = *do* putStrLn "Enter the id" id <- getLine putStrLn "Enter name" name <- getLine loop $ (Student (read id) (read name) ) : xs aremove :: [Student] -> IO ()aremove xs = *do* putStrLn "Enter the id" id <- getLine putStrLn "Enter name" name <- getLine loop $ delete (Student (read id) (read name) ) xs loop :: [Student] -> IO ()loop xs = *do* putStr $ "\n-------\nSelect an option\n" ++ "1) Add student\n" ++ "2) Remove student\n" ++ "3) Show all students\n" ++ "4) Exit\n" ++ "\t Your option: " option <- getLine putStrLn "\n------" *case* read option *of* 1 -> aadd xs 2 -> aremove xs 3 -> *do* ashow xs loop xs 4 -> putStrLn "God bye!"
My question are:
- When i ask for the data fof a student i repeat the code, cause i have to use fuctions using IO (), cuase i have to put something in the screen. Therefore i cant have a fuction that only return a Student. - loop $ (Student $ read id $ read name), is wrong why? - i think that there are best way to achive that i have done. Or is ok for a begginer that doesn't know functors or monads.
Sorry for my bad english, i am Argentinean.
Thanks in advance.
_______________________________________________ Beginners mailing list Beginners@haskell.org http://www.haskell.org/mailman/listinfo/beginners

Well there's plenty in you code that can be improved, first I would write this function :
prompt :: (Read a) => String -> IO a prompt str = do putStr str hFlush stdout fmap read getLine
The hFlush is there to avoid buffering problems (this is not Haskell specific). Then your aadd function become :
aadd xs = do id <- prompt "Enter the id : " name <- prompt "Enter name : " loop $ (Student id name) : xs
But then you'll still have a duplicated section in aremove, why not abstracting the Student selection :
studentPrompt :: IO Student studentPrompt = do id <- prompt "Enter the id : " name <- prompt "Enter name : " return (Student id name)
Just to give you a taste, you could also write this as :
studentPrompt = Student <$> prompt "Enter the id : " <*> prompt "Enter the name : "
using the Applicative typeclass (you'll probably see this later). Then aadd becomes :
aadd xs = do student <- studentPrompt loop (student : xs)
But writing a function for two lines and especially a function that's mixing program logic into it (the call to loop) is probably both unnecessary and confusing for someone reading your program (you should always strive to localize the interactive program logic and keep the rest pure or at least general purpose functions). So instead let's inline it in the loop :
loop studentList = do -- xs is a good list name when you don't know what's in it option <- prompt programOptions newStudentList <- case option of 1 -> fmap (: studentList) studentPrompt 2 -> fmap (`delete` studentList) studentPrompt 3 -> do ashow studentList; return studentList 4 -> do putStrLn "Good Bye !"; exitSuccess _ -> do putStrLn "Unknown option !"; return studentList loop newStudentList
--
Jedaï
On Sun, Dec 2, 2012 at 1:43 PM, Ezequiel Hernan Di Giorgi
Hola! Hallo! I made my first program to understand lists and something about datat types. I have some question about the following code...
import Data.List
data Student = Student { id :: Int, nombre :: String } deriving (Show, Eq)
main :: IO () main = do putStrLn "---\nStudent Magnament Program\n---" loop []
ashow :: [Student] -> IO () ashow [] = putStrLn "Empty list" ashow [x] = putStrLn $ show x ashow (x:xs)= do putStrLn $ show x ashow xs
aadd :: [Student] -> IO () aadd xs = do putStrLn "Enter the id" id <- getLine putStrLn "Enter name" name <- getLine loop $ (Student (read id) (read name) ) : xs
aremove :: [Student] -> IO () aremove xs = do putStrLn "Enter the id" id <- getLine putStrLn "Enter name" name <- getLine loop $ delete (Student (read id) (read name) ) xs
loop :: [Student] -> IO () loop xs = do putStr $ "\n-------\nSelect an option\n" ++ "1) Add student\n" ++ "2) Remove student\n" ++ "3) Show all students\n" ++ "4) Exit\n" ++ "\t Your option: " option <- getLine putStrLn "\n------" case read option of 1 -> aadd xs 2 -> aremove xs 3 -> do ashow xs loop xs 4 -> putStrLn "God bye!"
My question are:
When i ask for the data fof a student i repeat the code, cause i have to use fuctions using IO (), cuase i have to put something in the screen. Therefore i cant have a fuction that only return a Student. loop $ (Student $ read id $ read name), is wrong why? i think that there are best way to achive that i have done. Or is ok for a begginer that doesn't know functors or monads.
Sorry for my bad english, i am Argentinean.
Thanks in advance.
_______________________________________________ Beginners mailing list Beginners@haskell.org http://www.haskell.org/mailman/listinfo/beginners
participants (3)
-
Chaddaï Fouché
-
Ezequiel Hernan Di Giorgi
-
Reto Hablützel