haskell - 带有案例分析的“输入解析错误”
问题描述
我有以下主要功能,它应该向两个玩家询问他们的牌组,这些牌组是从另一个文件中的牌组库中选择的,然后使用这些输入运行一个循环。
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在块中的let
行为与在do
块外的行为不同do
。该语句let {d2 = deck 1};
格式错误,因为语法为let in
. 要解决此问题,您可以将其包装在do
(例如:)中do let {d2 = deck1};
,这应该可以解决解析错误,但这不是您想要的。
OP 中的代码有很多问题,我不确定从哪里开始,但这里有一些指示:
什么是甲板 1/2?
d1/2 的类型是什么?最初,它是一个字符串,因为您使用 填充它
getLine
,但随后您将其分配给deck1
,这可能不是字符串。let
do
必须遵循外部符号let BINDING in VALUE
。let 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
。
推荐阅读
- html - 桌面两列布局,移动一列,儿童不同顺序
- mongodb - BulkWriteError - MongoDB
- java - 使用流在 java 8 中拆分 entrySet 和过滤器
- c# - 如果我将虚拟关键字添加到属性,我需要帮助解决为什么实体框架不会保存
- mysql - 基于相似字段,使用同一表中另一行的数据更新一行
- javascript - 使用第一个下拉列表中匹配的数组值预弹出第二个下拉列表
- c# - 动态创建的内联可编辑数据表
- azure - 将 Microsoft Azure CDN 与现有站点一起使用
- salesforce - Informatica 会话中的 SFDC 批量 API 选项不起作用
- android - 不确定如何在重建时将 Cursor 转换为此方法的返回类型