user2240649
user2240649

Reputation: 89

Haskell couldn't match expected type char?

What im trying to do is call a function that I have already created into an input output main. The function im calling is a high order function shown below:

filmsByFan' f = map title $ filter (elem f . fans) testDatabase

This is the part of code thats spiting out the error message whenever I try to call this higher order function:

getInt :: IO Int
getInt = do str <- getLine
            return (read str :: Int)

main :: IO ()
main = do putStrLn "Enter 1. Add Film / 2. Display all Films / 3. Display film by Year / 4. Display film by fan / 5. Display film by actor and period / 6. Become Fan: "
          str <- getLine
          if str == "1"
            then do return ()
                else if str == "2"
            then do putStrLn (displayAllFilms' testDatabase "")
                else if str == "3"
                    then do putStrLn "Enter a film year: "
                        filmyear <- getInt
                        putStrLn (filmsByYear' filmyear)  <<< **ERROR HERE** (154:47)
                 else main

The rest of the code up until here work perfectly, ie if user enters '2' it will run displayAllFilms function (note the displayAllFilms function is NOT a higher order function)

Is it because the function is 'high order' therefore it will give this error?

Coursework v1.hs:154:47:
    Couldn't match expected type `Char' with actual type `[Char]'
    Expected type: String
      Actual type: [Title]
    In the return type of a call of `filmsByYear''
    In the first argument of `putStrLn', namely
      `(filmsByYear' filmyear)'

Any help would be much appreciated! thanks in advance!

Upvotes: 0

Views: 4169

Answers (1)

dave4420
dave4420

Reputation: 47052

Expected type: String

This means that at this point in the program, ghc expects to find an expression of type String (because the first argument of putStrLn must be a String).

  Actual type: [Title]

This means that the expression ghc actually found here, (filmsByYear' filmyear), has type [Title] (because the result given by filmsByYear' is a [Title]).

If the expected type and the actual type were the same, there wouldn't be an error.

Presumably you have type Title = String, so it's trying to unify String with [String] which fails. (And because type String = [Char], it's gets as far as trying to unify [Char] with [[Char]]... which still fails.)

Possible ways to fix this:

  • Turn the [String] into a String, e.g. by using unlines

    putStrLn (unlines (filmsByYear' filmyear))
    

    You might prefer to use intercalate from Data.List, depending on how you want the list formatted.

  • Call putStrLn on each string in the list in turn, by using mapM_

    mapM_ putStrLn (filmsByYear' filmyear)
    

n.b. Neither putStrLn nor filmsByYear' are higher order functions.

Upvotes: 5

Related Questions