[英]“Couldn't match type ‘[]’ with ‘IO’” error in Haskell
I am trying to make a list with Points (a datatype that I created), the idea is add an element in each iteration.我正在尝试使用 Points(我创建的一种数据类型)制作一个列表,这个想法是在每次迭代中添加一个元素。 Something is wrong.
出了点问题。
I have tried to put p
out of myLoop
but it doesn't seems to work either.我试图将
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
I am getting this output我得到这个 output
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)]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
First of all, do-notation is syntactic sugar with the following rules:首先,do-notation 是具有以下规则的语法糖:
do x <- mA
mB
roughly* desugars to mA >>= \x -> do mB
, where mA
has type Monad m => ma
and do mB
has type Monad m => mb
for some types m
, a
, and b
.大致* 脱糖为
mA >>= \x -> do mB
,其中mA
的类型为Monad m => ma
并且do mB
的类型为Monad m => mb
对于某些类型的m
、 a
和b
。
do mA
mB
desugars to mA >> do mB
, where mA
has type Monad m => ma
and do mB
has type Monad m => mb
for some types m
, a
, and b
.脱糖到
mA >> do mB
,其中mA
的类型为Monad m => ma
并且do mB
的类型为Monad m => mb
对于某些类型m
、 a
和b
。
do a
desugars to a
.脱糖
a
.
main
is a special name that represents the entrypoint of the program, and it has type IO a
for some type a
. main
是代表程序入口点的特殊名称,对于某些类型a
,它的类型为IO a
a 。 Because you define main = myLoop
, myLoop
must also have type IO a
.因为您定义
main = myLoop
, myLoop
还必须具有类型IO a
。
Therefore, in your myLoop
function:因此,在您的
myLoop
function 中:
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
the do
-block is working with the type m
= IO
. do
-block 使用m
= IO
类型。 Therefore, when you write p ++ [Point label (map getFloat coord)]
, the typechecker expects a value of type IO c
, for some type c
. Therefore, when you write
p ++ [Point label (map getFloat coord)]
, the typechecker expects a value of type IO c
, for some type c
.
However, p ++ [Point label (map getFloat coord)]
has type [Point]
, resulting in the type error Cannot match type '[]' with 'IO'
.但是,
p ++ [Point label (map getFloat coord)]
的类型为[Point]
,导致类型错误Cannot match type '[]' with 'IO'
。
As the type mismatch indicates, your code does not make sense.正如类型不匹配所表明的那样,您的代码没有意义。 I assume that you want to append
Point label (map getFloat coord)
to p
.我假设您想将 append
Point label (map getFloat coord)
到p
。 ++
does not mutate p
; ++
不会改变p
; it creates a new list!它会创建一个新列表! Idiomatic Haskell uses recursion to achieve what you want.
惯用的 Haskell 使用递归来实现您想要的。 The most direct way of fixing your code would be to do the following:
修复代码的最直接方法是执行以下操作:
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'
Here, myLoop
takes p
as a parameter and recursively passes an updated p
to itself after reading input.这里,
myLoop
将p
作为参数,并在读取输入后递归地将更新的p
传递给自身。 main
calls myLoop
with an argument of []
, which is the initial value of p
. main
使用参数[]
调用myLoop
,这是p
的初始值。
The Haskell Wikibook has a good explanation of do-notation . Haskell Wikibook对 do-notation 有很好的解释。 In general, I would recommend reading the Haskell Wikibook to better understand Haskell.
一般来说,我建议阅读 Haskell Wikibook 以更好地理解 Haskell。
*I say "roughly" because these aren't the exact rules. *我说“大致”是因为这些不是确切的规则。 The Wikibook article explains do-notation in depth.
Wikibook 文章深入解释了 do-notation。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.