应用程序中的类型错误-Haskell?

应用程序中的类型错误-Haskell?,haskell,types,Haskell,Types,类型Car=(String,[String],Int,[String]) 导致此错误的原因是什么?如何更正它?当您写入: putStr x ++ "\n" 这将按如下方式进行分析: (putStr x) ++ "\n" 这可能不是你想要的。试一试 putStr ( x ++ "\n" ) 还要注意:运算符的类型为a->[a]->[a],即第二个操作数必须是列表。但你有同样的东西左右: 这可以解释奇怪的错误消息,因为它会导致编译器将已经错误的类型与其列表形式相匹配。…请尝试 displayA

类型Car=(String,[String],Int,[String])

导致此错误的原因是什么?如何更正它?

当您写入:

putStr x ++ "\n"
这将按如下方式进行分析:

(putStr x) ++ "\n"
这可能不是你想要的。试一试

putStr ( x ++ "\n" )
还要注意:运算符的类型为a->[a]->[a],即第二个操作数必须是列表。但你有同样的东西左右: 这可以解释奇怪的错误消息,因为它会导致编译器将已经错误的类型与其列表形式相匹配。…

请尝试

displayAllCars :: [Car] -> IO ()
displayAllCars = mapM_ (putStrLn . show)
当然,这可以概括为

putStrLnAll :: Show a => [a] -> IO ()
putStrLnAll = mapM_ (putStrLn . show)
我想这是你想要的。您的代码几乎无法辨认,因为函数的名称与它们的实际功能不匹配

迭代汽车的一个示例:

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.
要将它们全部折叠成一个字符串,您可能需要这样的内容(假设存在
displayCar::Car->string
)。我再次避免显式递归,而是使用辅助函数

displayAllCars = foldl' (\acc val -> acc ++ "\n" ++ val) []
但是,我们可以使用递归:(通常的警告适用于任何非尾部优化的递归函数。如果列表较大,则会出现堆栈溢出。在生产代码中使用foldl版本。或者,如果可以接受向后列表,则foldr是最好的

displayAllCars [] = []
displayAllCars c:cs = displayCar c ++ "\n" ++ displayCar cs

除此之外,一个似乎还没有被指出的问题是,您试图将
putStr
(它需要一个
[Char]
)应用到
carToString
(一个函数,即使在给定参数后,仍然返回一个
IO()
)。由于
carToString
已经使用了
putStr
,只需在
displayAllCars
中去掉
putStr
,试试以下方法:

carToString :: [Car] -> [IO()]
carToString [] = [putStr ""]
carToString (x:xs) = putStr x ++ "\n" : carToString xs ++ "\n"

你不需要显示所有的汽车。你只需调用carToString函数并传递汽车列表

我想这与我试图用xs方法迭代项目列表有关,但仍然无法实现他想要的任何远程操作。代码严重损坏,无法修复。例如,请注意
(carToString testDatabase)
属于
IO()
。您不能将
IO()
传递给
putStr
。很可能他还想要其他东西,我会在几秒钟内给出答案。+1表示捕捉到错误。实际上:是同一行中的第二个错误,这一切都应该是IO()当然,最后他做了(printStr carToString)testdatabase-我不想看到这个消息:)@Ingo是的,我也注意到了,但我推断他指的是putStr(carToString testdatabase)@mathepic-也就是说,你做了更高阶的语义推断:)你能描述一下你打算用这段代码做什么吗?我为你修复了错误消息格式。函数名为putSTr,因为它放了一个字符串,但你可以使用putSTr xs,其中xs是一个汽车列表。你只需要putStr(showtestdatabase)哦,我明白了,你在上一篇评论中说的-这是否意味着它需要一种不同的类型?我需要添加换行符,以及如何引用车型中的每个项目?我有一个类型汽车的列表-我如何才能抓住每个项目汽车的个别项目?(很抱歉,我是一个初学者,你似乎知道你在说什么,谢谢!)@Ash你说的抓取最后一辆车的单个物品是什么意思?很可能您想使用(模式匹配):xs递归进行映射、折叠、列表理解或其他操作。@Ash基本上我认为您的carToString是用来显示汽车的。我想我们已经可以用Show来实现这一点了——如果你想的话,你可以实现你自己的程序,只要用它来代替Show就行了。它的类型应该是
displayCar::Car->String
。然后,我们的想法是对汽车列表进行一元映射,以显示每辆汽车。这里有一个汽车列表-我想要列表中的每一项,并能够得到该项的每一个子项?我觉得这很有道理,你明白我的意思吗?我已经尝试过递归,但无法确定如何从列表中的当前项中获取子项。@Ash,首先编写一个显示单个汽车的函数(比如showCar)。接下来,做地图展示我的车。生成的列表仍然需要换行符,因此(穿插“\n”(map showCar myCars))一切正常。
displayAllCars [] = []
displayAllCars c:cs = displayCar c ++ "\n" ++ displayCar cs
carToString :: [Car] -> [IO()]
carToString [] = [putStr ""]
carToString (x:xs) = putStr x ++ "\n" : carToString xs ++ "\n"