2016-12-02 15 views
-1

私はこの問題の答えを探していますが、役に立たないです。私はbsにマップされた後、私がcheckconsecの行から最初の配列をどのように渡すことができるかを調べようとしています。私は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は3つの引数をfooに適用し、foo (a b) cは2つの引数を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 
関連する問題