首页 > 解决方案 > 带有案例分析的“输入解析错误”

问题描述

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

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};

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

标签: haskell

解决方案


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

OP 中的代码有很多问题,我不确定从哪里开始,但这里有一些指示:

  • 什么是甲板 1/2?

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

  • letdo必须遵循外部符号let BINDING in VALUElet BINDING不是一个值,本身没有任何意义。此外,let BINDING in VALUE仅在 VALUE 中应用 BINDING。do'slet的特殊之处在于它将 BINDING 应用于它后面的所有行,但 BINDING 不会被覆盖。(例如:do { let x = ""; putStrLn x }实际上只是pure "" >>= \x -> putStrLn x(或者可能return "" >>= \x -> putStrLn x,或者可能(\x -> putStrLn x) "")的语法糖。

尝试完全避免 do 表示法,我认为您会感到困惑,因为 do 表示法允许 Haskell 看起来像 Java 一样命令式,但 Haskell 不是 Java。您应该从更纯的代码开始,然后再探索 Monads(和 IO)。只有这样,你才能真正明白do


推荐阅读