2016-12-02 5 views
-1

Я искал ответ на эту проблему, но безрезультатно. Я пытаюсь понять, как я могу передать первый массив из строк в checkconsec, после того как он будет сопоставлен с bs. Я пытаюсь использовать xs, но он не работает. Может ли кто-нибудь увидеть, что я делаю неправильно?Как передать функцию через карту в Haskell

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} 

** Редактировать: Я отредактировал это, чтобы включить весь мой код, надеюсь, это облегчит понимание моей проблемы. Я также исправил (насколько мне известно) типы checkconsec и помощника. Единственная ошибка, которую я получаю сейчас:

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. 
+0

Я не уверен, что понимаю ... Вы можете уточнить, что вы делаете? Что такое 'xs'? В 'checkConsec' вы пытаетесь передать 6 аргументов' helper', которая является функцией, которая принимает только 4 аргумента. –

ответ

2

Аргументы функции разделены пробелами. foo a b c применяет три аргумента к foo и foo (a b) c применяет два аргумента к foo. Приложение-приложение имеет наивысший приоритет. У меня нет оставшегося кода, но, я думаю, вы имели в виду следующее.

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 
Смежные вопросы