Reputation: 114
Hi Im trying to creating a UI where the user can choose in mainMenu to test out the function.
data Place = Place String Coord [Int]
deriving (Ord,Eq,Show,Read)
data Coord = Cord Double Double
deriving (Ord ,Eq ,Show ,Read)
placeName :: [Place] -> [String]
placeName [] = [""]
placeName plcs = [s | (Place s x(n:ns))<-plcs]
main :: IO ()
main = do putStrLn "Rainfall Map Without A Map"
placeFile <- readFile "place.txt"
let placeData = read placeFile
putStrLn ("\nFile Loaded "++ show(length placeData)++ "places")
mainMenu placeData
mainMenu :: [Place] -> IO()
mainMenu plcs = do
putStrLn(" 1. return the name of all places")
putStrLn(" 2. Display the average rain figures of a place")
putStrLn(" 3. Display places with formatted String")
putStrLn(" 4. Return the place that have zero raingfall")
putStrLn(" 5. Replace a place with new place")
putStrLn(" 6. Save and Exit")
putStr("Please insert a number: ")
choose<- getLine
numberChoose choose plcs
numberChoose :: String -> [Place]->IO()
numberChoose "1" plcs = first plcs
numberChoose "2" plcs = second plcs
numberChoose "3" plcs = third plcs
numberChoose "4" plcs = fourth plcs
numberChoose "5" plcs = fifth plcs
numberChoose "6" plcs = sixth plcs
numberChoose _ plcs = do
putStrLn ("Error!:-- Wrong Input")
mainMenu plcs
first :: [Place]->IO()
first plcs = do
putStrLn $ placeName plcs
mainMenu plcs
So my placeName function is just for returning a list of String from a Place and my first function is just for returning a list of string when the user insert the respective num. I assume that the data type of my mainMenu show be same as my first function. It give me the error:
• Couldn't match type ‘[Char]’ with ‘Char’
Expected type: String
Actual type: [String]
• In the second argument of ‘($)’, namely ‘placeName plcs’
In a stmt of a 'do' block: putStrLn $ placeName plcs
In the expression:
do putStrLn $ placeName plcs
mainMenu plcs
|
153 | putStrLn $ placeName plcs | ^^^^^^^^^^^^^^
Upvotes: 1
Views: 473
Reputation: 477804
putStrLn
has type putStrLn :: String -> IO ()
, so it prints one string, not a list of strings.
You can make use of mapM_ :: (Foldable f, Monad m) -> (a -> m b) -> f a -> m ()
to perform a monadic function on each element, so:
first :: [Place] -> IO ()
first plcs = do
mapM_ putStrLn (placeName plcs)
mainMenu plcs
or you can make use of unlines :: [String] -> String
to convert a list of strings to a string separated by new lines:
first :: [Place] -> IO ()
first plcs = do
putStrLn (unlines (placeName plcs))
mainMenu plcs
Upvotes: 2