我有以下主要功能,应该向两个玩家询问他们的套牌,这些套牌是从另一个文件中的套牌库中选择的,然后使用这些输入运行循环。
main :: IO()
main = do {
putStr "Player1 choose deck\n";
d1 <- getLine;
case d1 of
{
"deck1" -> let {d1 = deck1};
_ -> putStr "error"
};
putStr "Player2 choose deck\n";
d2 <- getLine;
case d2 of
{
"deck1" -> let {d2 = deck1};
_ -> putStr "error"
};
loop d1 d2
}
代码在行的分号上得到解析错误:
"deck1" -> let {d1 = deck1};
"deck1" -> let {d2 = deck1};
我多年来一直盯着这个,我确信它很简单,但是会欣赏一双新鲜的眼睛,看看有什么不对。 :)
答案 0 :(得分:0)
Haskell let
在do
块中的行为与在do
块之外的行为不同。语句let {d2 = deck 1};
格式不正确,因为语法为let in
。要解决此问题,您可以将其包装在do
(例如:do let {d2 = deck1};
)中,这应解决解析错误,但这不是您想要的。
OP中的代码有很多问题我不确定从哪里开始,但这里有一些指示:
什么是deck1 / 2?
d1 / 2的类型是什么?最初,它是一个字符串,因为您正在使用getLine
填充它,但之后您将其分配给deck1
,这可能不是字符串。
let
以外的do
符号必须遵循let BINDING in VALUE
。 let BINDING
不是一个价值,它本身没有任何意义。此外,let BINDING in VALUE
仅在VALUE中应用BINDING。 do
&#39; s let
的特殊之处在于它将BINDING应用于其后面的所有行,但BINDING不会被覆盖。 (例如:do { let x = ""; putStrLn x }
实际上只是pure "" >>= \x -> putStrLn x
(或许return "" >>= \x -> putStrLn x
,或者(\x -> putStrLn x) ""
)的语法糖。
尝试完全避免使用符号,我认为你会感到困惑,因为符号允许Haskell看起来像Java一样,但Haskell不是Java。您应该从更纯的代码开始,然后再探索Monads(和IO)。只有这样,你才能真正理解do
。