Haskell ';输入上的分析错误';结合案例分析

Haskell ';输入上的分析错误';结合案例分析,haskell,Haskell,我有下面的主要功能,它应该要求两个玩家提供他们的牌组,这些牌组是从另一个文件中的牌组库中选择的,然后使用这些输入运行一个循环 main :: IO() main = do { putStr "Player1 choose deck\n"; d1 <- getLine; case d1 of { "deck1" -> let {d1 = deck1};

我有下面的主要功能,它应该要求两个玩家提供他们的牌组,这些牌组是从另一个文件中的牌组库中选择的,然后使用这些输入运行一个循环

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
      }

我已经盯着它看了很久了,我相信它很简单,但我希望有一双新的眼睛来看看到底出了什么问题。:)

Haskell的
let
do
块中的行为与在
do
块外的行为不同。语句,
let{d2=deck 1}
格式不正确,因为语法是
let-in
。要解决此问题,可以将其包装在
do
(例如:
do-let{d2=deck1};
)中,这样可以解决解析错误,但这不是您想要的

OP中的代码有太多错误,我不确定从何处开始,但这里有一些提示:

  • 什么是1/2

  • d1/2的类型是什么?最初,它是一个字符串,因为您用
    getLine
    填充它,但随后您将它分配给
    deck1
    ,这可能不是一个字符串

  • let
    外部
    do
    符号必须跟随
    let绑定入值
    <代码>让绑定不是一个值,它本身没有任何意义。此外,
    let BINDING in VALUE
    仅在值中应用绑定
    do
    let
    的特殊之处在于它将绑定应用于它后面的所有行,但该绑定不会被覆盖。(例如:
    do{let x=”“;putStrLn x}
    实际上只是
    pure”“>=\x->putStrLn x
    (或者可能是
    return”“>=\x->putStrLn x
    ,或者可能是
    (\x->putStrLn x)”


尝试完全避免do符号,我认为您会感到困惑,因为do符号允许Haskell看起来像Java一样是命令式的,但Haskell不是Java。您应该从更纯的代码开始,然后再探索Monad(和IO)在那之后。只有到那时你才能真正理解
do

那么
let
语句的作用域通常是局部的。你不能“重新分配”(事实上,你一开始就不能分配)一个变量。所以这不起作用。您正试图在命令式编程中使用
let x=…
作为赋值,但Haskell不是命令式的,并且没有赋值。
let
可以定义局部变量,当作用域关闭时这些变量就会消失。如果您的代码是Java,则大致读取为
if(…){int d1=;}else{int d2=…;}loop(d1,d2);
将触发一个未定义的变量错误。下面的问题是苏格拉底式的,有启发性的;我希望你能带着这种动机来阅读和思考它。你认为
d1
应该在
putStr“Player2 choose-deck\n”
这行中有什么类型的
“deck1"
deck1
的类型?为什么?Haskell使用缩进来表示块结构;通常,由于某种原因,只有当您想在同一行或
数据
声明中填充所有内容时,才使用花括号和分号。请尝试去掉花括号和分号。@PaulJohnson,但大括号除外分号在这篇文章中是正确的…问题在于其他地方。因此,我的想法是有多个数据组可用,但是我只创建了一个,因此仅出于测试目的,
d1
d2
都应该是
deck1
deck1
存储在一个绝望的文件中,并且具有
[(String,Int,Int)
。我想要实现的是,在游戏开始之前,也就是在循环之前,玩家被问到他们想要使用哪一副牌,然后游戏开始时使用那些选定的牌。
 "deck1" -> let {d1 = deck1};
 "deck1" -> let {d2 = deck1};