Type error in application - Haskell?
type Car = (String, [String], Int, [String])
carToString :: [Car] -> IO()
carToString [] = putStr ""
carToString (x:xs) = putStr x ++ "\n" : putStr xs ++ "\n"
displayAllCars :: IO ()
displayAllCars = putStr carToString testDatabase --< test 开发者_运维问答data in the format of type Car
this gives me the error:
ERROR file:.\template.hs:26 - Type error in application
*** Expression : putStr xs
*** Term : xs
*** Type : [([Char],[[Char]],Int,[[Char]])]
*** Does not match : [Char]
What is the cause of this error and how do I correct it?
Try instead
displayAllCars :: [Car] -> IO ()
displayAllCars = mapM_ (putStrLn . show)
naturally this generalizes to something like
putStrLnAll :: Show a => [a] -> IO ()
putStrLnAll = mapM_ (putStrLn . show)
I think this does what you desire. Your code is pretty much indecipherable because the names of the functions don't match what they actually do.
An example of iterating over the Cars:
iter [] = ?
iter x@(v1, v2, v3, v4):xs = do stuff with x (the car) and its values v1, v2, v3, v4 then call iter xs.
To fold them all into a string, you probably want something like (assuming displayCar :: Car -> String
exists). I'm again avoiding explicit recursion here in favor of using an auxiliary function.
displayAllCars = foldl' (\acc val -> acc ++ "\n" ++ val) []
However, we could use recursion: (The usual warning applies here as with any non-tail-optimized recursion function. You will get a stack overflow if the list is large. Use the foldl' version in production code. Alternatively foldr is the best if a backwards list is acceptable.
displayAllCars [] = []
displayAllCars c:cs = displayCar c ++ "\n" ++ displayCar cs
When you write:
putStr x ++ "\n"
this will be parsed like so:
(putStr x) ++ "\n"
This is probably not what you want. Try
putStr ( x ++ "\n" )
Note also that the : operator has type a -> [a] -> [a], i.e. the second operand must be a list. But you have the same kind of thing left and right of : This would explain the exotic error message, as it induces the compiler to match an already wrong type with its list form .....
Among other things, the one problem that doesn't seem to have been pointed out yet is that you're trying to apply putStr
(which expects a [Char]
) to carToString
(a function which, even after being given parameters, returns an IO ()
). As carToString
already makes use of putStr
, just get rid of the putStr
in displayAllCars
.
Try this :
carToString :: [Car] -> [IO()]
carToString [] = [putStr ""]
carToString (x:xs) = putStr x ++ "\n" : carToString xs ++ "\n"
You don' need display all cars. You can just call the carToString function and pass the list of Car
精彩评论