import Control.Monad import Data.Monoid dotest x = do if x then return "Test" else return "OK" type KnightPos = (Int, Int) moveKnight :: KnightPos -> [KnightPos] moveKnight (c, r) = do (c', r') <- [(c+2,r-1),(c+2,r+1),(c-2,r-1),(c-2,r+1) ,(c+1,r-2),(c+1,r+2),(c-1,r-2),(c-1,r+2)] guard (c' `elem` [1..8] && r' `elem` [1..8]) return (c', r') filterDup :: [KnightPos] -> [KnightPos] filterDup [] = [] filterDup (x:xr) = x:(filterDup $ filter (x/=) xr) singleStep x = filterDup $ x >>= moveKnight multiStep :: Int -> [KnightPos] -> [KnightPos] multiStep 0 x = x multiStep n x = multiStep (n-1) (singleStep x) applyLog :: (Monoid m) => (a, m) -> (a -> (b, m)) -> (b, m) applyLog (x, log) f = let (y, newLog) = f x in (y, log `mappend` newLog)