What can be the problem with my haskell code and how can I fix it?

Viewed 167

deadNeighbors: Give a list of empty cells that have a living cellular neighbor in that generation. Make sure that each cell is listed only once!

Something not work with my deadNeighbors function, but I do not know what is wrong about it. Can anybody help me to fix deadNeighbors ?

type Coordinate = (Integer, Integer)

type Generation = [Coordinate]

single :: Generation
single = [ (42, 42) ]

row :: Generation
row = [ (10, 1), (10, 2), (10, 3) ]

Code:

neighbors :: Coordinate -> [Coordinate]
neighbors (x,y) = [(x-1,y-1), (x-1,y), (x-1,y+1), (x ,y-1), (x,y+1), (x+1,y-1), (x+1,y), (x+1,y+1)]

alive :: Generation -> Coordinate -> Bool 
alive x y = elem y x  

livingNeighbors :: Generation -> Coordinate -> Int
livingNeighbors a = length .filter (alive a) . neighbors

staysAlive :: Generation -> Coordinate -> Bool
staysAlive a b
 | alive a b = livingNeighbors a b `elem` [2,3]
 | otherwise = livingNeighbors a b `elem` [3]

Problems:

deadNeighbors :: Generation -> [Coordinate]
deadNeighbors (neighbors (x,y)) 
 |(alive (x,y)) = Nothing
 |otherwise = [] ++ (x,y)
 

Examples:

sort (deadNeighbors single) == sort [(41.41), (41.42), (41.43), (42.41), (42.43), (43.41), (43.42) , (43.43)]
sort (deadNeighbors row) == sort [(9.0), (9.1), (9.2), (10.0), (11.0), (11.1), (11.2) , (9.3), (11.3), (9.4), (10.4), (11.4)]
1 Answers

Let's go over deadNeighbors function line by line:

(the type signature looks fine)

deadNeighbors (neighbors (x,y)) 

This is a clause of the deadNeighbors function and seems to use pattern matching notation, however you use the function neighbors in the pattern match. That is not allowed. I don't really know what your intention is here, so I cannot suggest a way to fix this.

 |(alive (x,y)) = Nothing

Here you are using a guard correctly, but the alive function requires the generation in addition to the coordinate. You should pass both as arguments here.

Also, you are returning Nothing which has type Maybe a for some a. But the signature of the deadNeighbors function indicates it should return a [Coordinate]. Perhaps you intended to write [] (the empty list)?

 |otherwise = [] ++ (x,y)

Here you are using the ++ operator, which expects two lists as arguments, with an empty list [] as argument and a coordinate (x,y). The coordinate type is not a list, so it is not compatible with the ++ operator. Perhaps you intended (x,y) : [] or just [(x,y)] (which means the same thing but is slightly prettier)?

Related