すごいH本のチェスの演習問題書いた

「すごいHaskellたのしく学ぼう!」の308ページの、3手で到達できるときその途中経路を出力する演習問題を書いてみた

import Control.Monad

type Route = [(Int, Int)]

routeStart :: (Int, Int) -> Route
routeStart x = [x]

inBoard :: Route -> Bool 
inBoard (x:xs) = x `elem` [(a,b) | a <- [1..8], b <- [1..8]]

possibleRoute :: Route -> [Route]
possibleRoute all@((x,y):xs) = do
  (dx,dy) <- [(2,1), (-2,1), (2,-1), (-2,-1), (1,2), (1,-2), (-1,2), (-1,-2)]
  let p = (x+dx, y+dy)
      r = p:all
  guard $ inBoard r
  return r

canReachIn3 :: (Int, Int) -> (Int, Int) -> [Route]
canReachIn3 s g = filter (\x -> head x == g)
                  (return (routeStart s) >>= possibleRoute >>= possibleRoute
                  >>= possibleRoute)