haskellothello

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


I'm working on a Haskell implementation of the board game Othello and still at the beginning of the process. I'm currently trying to create a function that will display the board. At the minute I am simply trying to get the function to output the coordinate value of each cell. My idea is that I can recurse through each row and then through each cell and output the value of each. I then call this function in main and output the board as a string.

I'm having trouble with string concatenations however and run into the error "Expected type: String, Actual type: [[Char]].

I know that in Haskell, String is essentially a pseudonym for [Char] but I can't see why I am getting a [[Char]] when I use the "++" function.

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) ++ " ")

Ideally I want this function to output this:

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

Sorry if my code isn't very readable or my ideas unclear, I'm still trying to learn the basics of Haskell. Thank for your time and help in advance.


Solution

  • This is because

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

    is a [String], not a String, and you can't append a String to a [String].
    (drawBoardCell and drawBoardRow produce Strings, so [drawBoardRow ...]is a [String], so the entire thing is also a [String].)

    You need to stick to ++.

    It also looks like you're using let and return as if this were some other programming language that you already know.
    If you do know some other programming language, now is a good time to forget that you do.

    You don't need return at all here, and most of your lets serve no purpose.

    My own beginner-level take would look like this:

    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 ++ " "