I am currently working on a chessgame in Haskell. Here is my function that evaluates to True, when you feed it the right parameters for castling on the kingsside. (the problem is in part 1 & 2, look at the comments). I tried to use function composition to find a more concise solution, but it didn't really work out for me. I'd be glad if someone could take a glance at what i did and explain where i went wrong ... thanks a lot in advance
shortCastlingWhite :: Int -> Int -> GameState -> Bool
shortCastlingWhite start end state@(board,_) =
(board !! 95 == 10) && -- on 95=(e,1) is a white King
(board !! 98 == 11) && -- on 98=(h,8) is a white Rook
(start == 95 && end == 97) && -- move from (e,1) to 97=(g,1)
(not $ (wasMoved state 95 || wasMoved state 98) && -- King and Tower weren't moved until now
(not $ (indexOccupied 96 state || -- part 1 !! 96=(f,1) and (g,1) are unoccupied
(indexOccupied 97 state) || -- part 1
(isThreatenedBy Black 95 state) || -- part 2 !! neither (e,1) nor (f,1) or (g,1) are threatened by Black Figures
(isThreatenedBy Black 96 state) || -- part 2
(isThreatenedBy Black 97 state))) -- part 2
here are the typesignatures for the used functions
isThreatenedBy :: Colour -> GameState -> Int -> Bool
wasMoved :: GameState -> Int -> Bool
i wanted to rewrite the very verbose parts 1 and 2 as :
all (swap indexUnoccupied state) [96,97] &&
(all ((not.isThreatenedBy) Black state) [95,96,97]) &&
(all ((not.wasMoved) state) [95,98])
where swap f a b = f b a
--
but i cant get around the errormessage of :
newchess.hs:240:181:
Couldn't match expected type `GameState -> a0 -> Bool`
with actual type `Bool`
The function `not . isThreatenedBy` is applied to two arguments,
but its type `Colour -> Bool` has only one
In the first argument of `all`, namely
`((not . isThreatenedBy) Black state)`
In the first argument of `(&&)', namely
`(all ((not . isThreatenedBy) Black state) [95, 96, 97])`
isThreatenedBy :: Colour -> GameState -> Int -> Bool
when i compose not and isThreatenedBy i should get
a function f = (not . isThreatenedBy)
of type
f :: Colour -> GameState -> Int -> Bool
but really i get something like Colour -> Bool
i think.
Then i partially apply it with values of Colour and GameState
and the resulting function f' should be of type
f' :: Int -> Bool
and then i kinda map it over the list [95,96,97]
and see
if every element satisfies f'
via all
or so was the plan ...
newchess.hs:240:186:
Couldn't match type `GameState -> Int -> Bool` with `Bool`
Expected type: Colour -> Bool
Actual type: Colour -> GameState -> Int -> Bool
Probable cause: `isThreatenedBy` is applied to too few arguments
In the second argument of `(.)`, namely `isThreatenedBy`
In the expression: not . isThreatenedBy
its odd that (not . wasMoved) is applied to too many arguments in error1 and probably to too few in error 2 , but i cant move the list elements inside the brackets , otherwise i could just go back to the point from that i started
newchess.hs:240:238:
Couldn't match expected type `a1 -> Bool` with actual type `Bool`
Possible cause: `not . wasMoved` is applied to too many arguments
In the first argument of `all`, namely `((not . wasMoved) state)`
In the second argument of `(&&)`, namely
`(all ((not . wasMoved) state) [95, 98])`
same as above in error 1 (just this time with wasMoved)
newchess.hs:240:243:
Couldn't match type `Int -> Bool' with `Bool`
Expected type: GameState -> Bool
Actual type: GameState -> Int -> Bool
Probable cause: `wasMoved` is applied to too few arguments
In the second argument of `(.)`, namely `wasMoved`
In the expression: not . wasMoved
Failed, modules loaded: none.
as in error 2 i think
swap
is already provided as theflip
function. - Bakuriuswap
is also "taken" forswap :: (a,b) -> (b,a)
inData.Tuple
. - dfeuer