dtan
dtan

Reputation: 69

Applying a list of functions on a list

I am working on making a step-by-step exercise in making a Sudoku solver from http://www.cse.chalmers.se/edu/year/2013/course/TDA555/lab3.html. Here I'm trying to express the row, column and box constraints for the Sudok

data Sudoku = Sudoku { getSudoku :: [[Maybe Int]] } deriving (Show, Eq)

rows :: Sudoku -> [[Maybe Int]]
rows (Sudoku rs) = rs

columns :: Sudoku -> [[Maybe Int]]
columns = transpose . rows

boxes :: Sudoku -> [[Maybe Int]]
boxes s = a ++ b ++ c
    where a = map (concat . take 3) s1
          b = map (concat . take 3 . drop 3) s1
          c = map (concat . drop 6) s1
          s1 = transpose . map (\xs -> [take 3 xs,take 3 (drop 3 xs), drop 6 xs]) $ rows s

I managed to get it to work but I want to refactor the 3 functions applied on s1 to get a,b,c into a list. I tried with <*> but somehow can't get it to work. Thanks

Upvotes: 0

Views: 135

Answers (1)

user2407038
user2407038

Reputation: 14578

You can write it using Applicative if you really want

boxes2 s = concat $ [a,b,c] <*> [s1]

This is just the same as

concatMap ($s1) [a,b,c] 

Alternatively, you can do this:

boxes3 :: Sudoku -> [[Maybe Int]]
boxes3 = map concat . concat . map (f . transpose) . f . getSudoku
  where f = unfoldr (\x -> if null x then Nothing else Just $ splitAt 3 x)

Upvotes: 3

Related Questions