AndieM
AndieM

Reputation: 39

How to pass a function through map in Haskell

I have been searching for an answer to this problem but to no avail. I am trying to figure out how i can pass the first array from rows in checkconsec, after it is mapped to bs. I am trying to use xs but it doesn't work. Can anyone see what I'm doing wrong?

import Data.Maybe
import Data.List

data Piece = Yellow | Red deriving Eq
type Column = [Piece]
type Board = [Column]

data BoardState = BS {
theBoard :: Board,
lastMove :: Piece,
numColumns :: Int,
numRows :: Int, 
numToConnect :: Int}

---------- Make Move -----------
-- This function makes a move on a Boardstate, first checks if the column is full or if the column exists or not.
-- If true returns just a boardstate, if false returns nothing
makeMove :: BoardState -> Int -> Maybe BoardState   
makeMove bs n = case ((checkLegal bs n) && (checkNotFull bs (columns bs !! (n-1)))) of
         True -> Just (updateBoard bs n)                                
         False -> Nothing

-- Checks if the move is legal, i.e. if the column to be moved into exists
checkLegal :: BoardState -> Int -> Bool
checkLegal bs i = case (i <= (numColumns bs) && (i /= 0)) of
           True -> True
           False -> False

-- Checks if the desired column is not full.
checkNotFull :: BoardState -> [Maybe Piece] ->Bool
checkNotFull bs a  = case (length (catMaybes a)< (numRows bs)) of
         True ->True
         False -> False


-----------Parts of Board-----------
-- This function repeats nothing over and over.
repeatNothing :: Int -> [Maybe a]
repeatNothing m = replicate m Nothing

-- This function pads a list so that the resulting list is of the appropriate length
padN :: [a] -> Int -> [Maybe a]
padN xs n = (map Just xs) ++ repeatNothing (n - (length xs))

-- This function finds all of the columns of the board
columns :: BoardState -> [[Maybe Piece]]
columns bs = map (\col -> padN col (numRows bs)) (theBoard bs) 

-- This function finds all the rows of the board
rows :: BoardState -> [[Maybe Piece]]
rows bs = map (\col -> padN col (numRows bs)) (transpose(theBoard bs))

-- This function will find the forward diagonals, but first gets the rows and the calls diagonals on the already padded
-- rows
diagonalsForward :: BoardState -> [[Maybe Piece]]
diagonalsForward bs = (diagonals (rows(bs)))

-- This function will find the backward diagonals, but first the rows are found, then the resulting grid is rotated
-- 90 degrees, followed by calling diagonals, which will then return the backwards diagonals, however in the wrong order
-- so then reverse is called on each list in order to get the correct order of the diagonals
diagonalsBackward :: BoardState -> [[Maybe Piece]]
diagonalsBackward bs = map reverse (diagonals((map reverse.transpose)(rows(bs))))

-- Because this section of code is cited above, the detailed axplanation of how it works is attached in another document
diagonals :: [[t]] -> [[t]]
diagonals [] = []
diagonals ([]:xss) = xss
diagonals xss = zipWith (++) (map ((:[]).head) xss ++ repeat[])
        ([] : (diagonals (map tail xss)))

-----------Check Win ---------------

checkWin :: BoardState -> [[Maybe Piece]]
checkWin bs = map (checkConsec bs) (rows bs)

checkConsec :: BoardState -> [[Maybe Piece]] -> [Maybe Piece]
checkConsec bs (x:xs) = helper (numToConnect bs) 1 (lastMove bs) x

helper :: Int -> Int -> Piece  -> [Maybe Piece] -> [Maybe Piece]
helper = undefined

{-
helper numToCon cntr color (x:xs) = [];
helper numToCon cntr color (x:xs) = if cntr 0 then Nothing -- cntr initialized to 1
else case (color, x) of
(Just Yellow, Just Yellow) -> helper numToCon (cntr+1) color
(Just Yellow, Nothing) -> helper numToCon(cntr=1) color
(Just Yellow, Just Red) -> helper numToCon(cntr=1) color
(Just Red, Just Red) -> helper numToCon(cntr+1) color
(Just Red, Nothing) -> helper numToCon(cntr=1) color
(Just Red, Just Yellow) -> helper numToCon(cntr=1) color
-}

---------Update Board------------
-- This function splits a list into three separate pieces, the position of the split is determined by the parameter n 
split3:: Int -> [Column] -> ([Column], Column, [Column])
split3 n xs = let (ys,(z:zs)) = (take (n-1) xs, drop (n-1) xs) in (ys, z, zs)

-- Calls split3 on the board 
splitBoard :: BoardState -> Int -> [Column]
splitBoard bs n = addPiece bs (split3 n (theBoard bs))

-- Adds a piece to the desired column of the board
addPiece :: BoardState -> ([Column], Column, [Column]) -> [Column]
addPiece bs (x,y,z) = x ++ (y ++ [lastMove bs]):z 

-- Updates the board to the new state, after adding a piece (or not) and updating the lastMove 
updateBoard :: BoardState -> Int -> BoardState
updateBoard bs n = case (lastMove bs) of
           Yellow -> BS {theBoard = splitBoard bs n,
       lastMove = Red,  
       numColumns = numColumns bs,
       numRows = numRows bs,    
       numToConnect = numToConnect bs}
           Red -> BS {theBoard = splitBoard  bs n,
       lastMove = Yellow,
       numColumns = numColumns bs,
       numRows = numRows bs,
       numToConnect = numToConnect bs}

** Edit: I have edited this to include all of my code, hopefully this will make it easier to understand my problem. I also fixed (to the best of my knowledge) the types of checkconsec and helper. The only error I am getting now is:

Couldn't match type ‘Maybe Piece’ with ‘[Maybe Piece]’
    Expected type: [[[Maybe Piece]]]
      Actual type: [[Maybe Piece]]
    In the second argument of ‘map’, namely ‘(rows bs)’
    In the expression: map (checkConsec bs) (rows bs)
Failed, modules loaded: none.

Upvotes: 0

Views: 185

Answers (1)

zeronone
zeronone

Reputation: 3041

Arguments to a function is separated by spaces. foo a b c applies three arguments to foo and foo (a b) c applies two arguments to foo. The function application has the highest precedence. I don't have the remaining of your code, but I guess you meant the following.

checkWin :: BoardState -> [[Maybe Piece]]
checkWin bs = map (checkConsec bs) (rows bs)

checkConsec :: BoardState -> [Maybe Piece] -> [Maybe Piece]
checkConsec bs = helper (numToConnect bs) 1 (lastMove bs) xs 

helper :: Int -> Int -> Maybe Piece -> [Maybe Piece] -> [Maybe Piece]
helper = undefined

Upvotes: 2

Related Questions