我正在尝试用Points(我创建的数据类型)列出一个列表,这个想法是在每次迭代中添加一个元素。出了点问题。
我尝试将p
从myLoop
中剔除,但这似乎也不起作用。
main = myLoop
myLoop = do
let p = []
done <- isEOF
if done
then putStrLn ""
else do inp <- getLine
let (label:coord) = words inp
p ++ [Point label (map getFloat coord)]
-- print (pointerList)
myLoop
我得到了这个输出
trabalho.hs:30:23: error:
• Couldn't match type ‘[]’ with ‘IO’
Expected type: IO Point
Actual type: [Point]
• In a stmt of a 'do' block:
p ++ [Point label (map getFloat coord)]
In the expression:
do inp <- getLine
let (label : coord) = words inp
p ++ [Point label (map getFloat coord)]
myLoop
In a stmt of a 'do' block:
if done then
putStrLn ""
else
do inp <- getLine
let (label : coord) = ...
p ++ [Point label (map getFloat coord)]
....
|
30 | p ++ [Point label (map getFloat coord)]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
答案 0 :(得分:5)
首先,do表示法是具有以下规则的语法糖:
do x <- mA
mB
大约*减少到mA >>= \x -> do mB
,其中mA
的类型为Monad m => m a
,而do mB
的类型为Monad m => m b
,某些类型的m
,{{ 1}}和a
。
b
对do mA
mB
的贬低,其中对于某些类型mA >> do mB
,{{1},mA
的类型为Monad m => m a
,do mB
的类型为Monad m => m b
。 }和m
。
a
对b
不满意。
do a
是一个特殊名称,代表程序的入口点,对于某些类型a
,它的类型为main
。因为您定义了IO a
,所以a
也必须具有类型main = myLoop
。
因此,在您的myLoop
函数中:
IO a
myLoop
块正在使用myLoop = do
let p = []
done <- isEOF
if done
then putStrLn ""
else do inp <- getLine
let (label:coord) = words inp
p ++ [Point label (map getFloat coord)]
-- print (pointerList)
myLoop
= do
类型。因此,当您编写m
时,对于某些类型IO
,类型检查器需要类型为p ++ [Point label (map getFloat coord)]
的值。
但是,IO c
的类型为c
,导致类型错误为p ++ [Point label (map getFloat coord)]
。
如类型不匹配所指示,您的代码没有意义。我假设您要将[Point]
附加到Cannot match type '[]' with 'IO'
。 Point label (map getFloat coord)
不会 突变p
;它会创建一个新列表! Idiomatic Haskell使用递归来实现所需的功能。修改代码最直接的方法是执行以下操作:
++
在这里,p
以main = myLoop []
myLoop p = do
done <- isEOF
if done
then putStrLn ""
else do inp <- getLine
let (label:coord) = words inp
let p' = p ++ [Point label (map getFloat coord)]
myLoop p'
作为参数,并在读取输入后将更新的myLoop
递归传递给它自己。 p
用p
的参数main
的初始值来调用myLoop
。
Haskell Wikibook具有a good explanation of do-notation。通常,我建议阅读Haskell Wikibook,以更好地了解Haskell。
*我之所以说“大致”,是因为这不是确切的规则。 Wikibook文章深入解释了do-notation。