预期类型:字符串,Haskell 中的实际类型 [[Char]] 错误消息

Expected type: String, Actual type [[Char]] error message in Haskell

我正在研究 Haskell 棋盘游戏 Othello 的实现,但仍处于该过程的开始阶段。 我目前正在尝试创建一个显示板的功能。目前我只是想获取函数来输出每个单元格的坐标值。 我的想法是我可以递归遍历每一行,然后遍历每个单元格并输出每个单元格的值。 然后我在 main 中调用这个函数并将电路板作为字符串输出。

我在字符串连接方面遇到了问题,但是 运行 出现错误“预期类型:字符串,实际类型:[[Char]]。

我知道在 Haskell 中,String 本质上是 [Char] 的假名,但我不明白为什么我在使用“++”函数时会得到 [[Char]]。

showGameState :: GameState -> String
showGameState g =
      let boardStart = (1,1)
      in drawBoard boardStart (board g) (size $ board g)

//the standard board is size 8*8
//here im trying to recursively call the drawBoardRow function increasing the row each time
drawBoard :: (Int, Int) -> Board -> Int -> String
drawBoard pos b len =
      let string = ""
      in if len > 0
              then string ++ (drawBoardRow pos (size b) : [drawBoard (fst pos, snd pos +1) (b) (len - 1)])
              else return string


//callig the drawBoardCell function recursively increasing the column position each time
drawBoardRow :: (Int, Int) -> Int -> String
drawBoardRow pos len =
      let string = ""
      in if len > 0
              then string ++ (drawBoardCell pos : [drawBoardRow(fst pos + 1, snd pos) (len - 1)]) ++ "\n"
              else return string


//At this stage i simply want to add each the coordinate of the cell the string containing
//the row
drawBoardCell :: (Int, Int) -> String
drawBoardCell pos =
      let string = ""
      in return (string ++ " " ++  show(fst pos) ++ show(snd pos) ++ " ")

理想情况下我希望这个函数输出这个:

11 21 31 41 51 61 71 81
12 22 32 42 52 62 72 82
13 23 33 43 53 63 73 83
14 24 34 44 54 64 74 84
15 25 35 45 55 65 75 85
16 26 36 46 56 66 76 86
17 27 37 47 57 67 77 78
18 28 38 48 58 68 78 88

抱歉,如果我的代码可读性不佳或我的想法不清楚,我仍在努力学习 Haskell 的基础知识。 提前感谢您的时间和帮助。

这是因为您正在使用 return 就像这是 Java 之类的。删除您在此处向我们展示的所有 return,然后重试,它应该会起作用。

这是因为

(drawBoardCell pos : [drawBoardRow(fst pos + 1, snd pos) (len - 1)])

[String],而不是 String,您不能将 String 附加到 [String]
drawBoardCelldrawBoardRow 产生 String,所以 [drawBoardRow ...] 是一个 [String],所以整个事情也是一个 [String]。)

你需要坚持++

看起来您正在使用 letreturn,就好像这是您已经知道的其他编程语言一样。
如果您确实了解其他一些编程语言,那么现在是忘记您了解的好时机。

你在这里根本不需要 return,而且你的大部分 let 都没有用。

我自己的初学者水平是这样的:

drawBoard :: (Int, Int) -> Board -> Int -> String
drawBoard _ _ 0 = ""
drawBoard pos@(x,y) b len =
  drawBoardRow pos (size b) ++ drawBoard (x, y + 1) b (len - 1)

drawBoardRow :: (Int, Int) -> Int -> String
drawBoardRow _ 0 = ""
drawBoardRow pos@(x, y) len =
  drawBoardCell pos ++ drawBoardRow(x + 1, y) (len - 1) ++ "\n"

drawBoardCell :: (Int, Int) -> String
drawBoardCell (x, y) = " " ++  show x ++ show y ++ " "