Anonyum
Anonyum

Reputation: 114

Haskell IO return Couldn't match type ‘[Char]’ with ‘Char’ Expected type: String Actual type: [String]

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

Answers (1)

willeM_ Van Onsem
willeM_ Van Onsem

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

Related Questions