Understanding haskells data types and constructors (specifically where you use another data type in a data type)

Viewed 89

As an assignment we were given these data types, and I need to make a function that get a row ([Cell]) and returns Player X, Player O or Nothing depending on the row.

module TicTacToe where
import Data.Maybe

data Player = X | O deriving Eq
data Cell = E | P Player deriving Eq
data State = Running | GameOver (Maybe Player) deriving Eq

type Size = Int
type Board = [[Cell]]
type Game = (Size, Board, Player, State)
whoWonOnRow :: [Cell] -> Maybe Player
whoWonOnRow c
    | head c == E && all (== head c) c = Nothing
    | (head c == P X || head c == P O) && all (== head c) c = Just (head c)
    | otherwise = Nothing

My understanding is that the data type Cell can have 2 values: E or P which is a Player data type. Now I don't understand what the problem is because head c will be either E or a Player, so I compare it to E and and a P Player X and Y.

If the first Cell is empty (E) than we know that nobody won and, we can return Nothing. If it's a Player than we check that every other Cell is also that players. If so X or O wins, otherwise Nothing.

1 Answers

head c has as type Cell, but your whoWonOnRow function is supposed to return a Maybe Player, not a Maybe Cell.

You can implement this with:

whoWonOnRow :: [Cell] -> Maybe Player
whoWonOnRow (e@(P x) : cs) | all (e ==) cs = Just x  -- x, not e (head c)
whoWonOnRow _ = Nothing
Related