2

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
  • 1
    As a general thumb rule, prefer pattern matching to head, tail, !!, length, == when it makes sense. Compare your attempt with Willem's below. Recall that head,tail,!! can make your program crash if the list is empty, while (exhaustive) pattern matching is safe. Commented Nov 28, 2021 at 9:01

1 Answer 1

4

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
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.