List &引用;不能';t匹配类型‘;[]和#x2019;与‘;IO’&引用;哈斯克尔错误

List &引用;不能';t匹配类型‘;[]和#x2019;与‘;IO’&引用;哈斯克尔错误,list,haskell,type-mismatch,io-monad,do-notation,List,Haskell,Type Mismatch,Io Monad,Do Notation,我试图用点(我创建的数据类型)制作一个列表,想法是在每次迭代中添加一个元素。有点不对劲 我曾试图将p从myLoop中删除,但它似乎也不起作用 main=myLoop myLoop=do 设p=[] done首先,do表示法是一种语法糖,有以下规则: do x <- mA mB 对于某些类型的m,mA具有类型Monad m=>mA,do-mB具有类型Monad m=>mB,其中mA具有类型m,a和b do mA mB do a 除砂器至a main是一个表示程序入口点的特殊

我试图用点(我创建的数据类型)制作一个列表,想法是在每次迭代中添加一个元素。有点不对劲

我曾试图将
p
myLoop
中删除,但它似乎也不起作用

main=myLoop
myLoop=do
设p=[]

done首先,do表示法是一种语法糖,有以下规则:

do x <- mA
   mB
对于某些类型的
m
mA
具有类型
Monad m=>mA
do-mB
具有类型
Monad m=>mB
,其中
mA
具有类型
m
a
b

do mA
   mB
do a
除砂器至
a

main
是一个表示程序入口点的特殊名称,对于某些类型
a
,它具有类型
IO 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 
这里,
myLoop
p
作为参数,并在读取输入后递归地将更新后的
p
传递给自身
main
调用
myLoop
,参数为
[]
,这是
p
的初始值

Haskell维基百科已经发布了。总的来说,我建议阅读Haskell维基,以更好地理解Haskell


*我说“粗略”是因为这些不是确切的规则。Wikibook文章深入解释了do符号。

Haskell中的变量是不可变的。您不能在程序运行期间更改它们的值。改用递归。
p++[…]
不会改变
p
。它会创建一个新列表。因为这发生在返回类型为IO的do块中,编译器抱怨这是一个列表而不是IO操作。给
myLoop
一个list参数,首先用
main
中的空列表调用它,并在将新列表传递给递归调用之前附加到它。修复它之后,可能会评论一下
p
最终是如何不被使用的,修复后,算法是二次的。可能的解决方法:正反两面;使用差异列表(
(xs++)
)编码而不是普通的
++
;或者将
do
块重新构造为非尾部递归的类似序列的结构(
getPoints=~[p:ps | p
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 
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'