I have two lists -- one is a grid list of tuples and the other one is a list of coordinates -- to be compared, such that the list of coordinates is always a sublist of the grid list. Now I want to check each tuple in the grid list whether it's in the coordinates list or not. If there exists one, substitute the tuple in the grid list with a "#" and if not, substitute with a "_".
Below is my best attempt and it never works.
getHash :: [(Int,Int)] -> [(Int,Int)] -> [String]
getHash [(x1,y1)] [(x2,y2)] | (x1,y1) `elem` [(x2,y2)] : (x1,y1) = "#"
| otherwise (x1,y1) = "_"
where (x1,y1) <- [(x1,y1)]
CodePudding user response:
You want to replace each element in a list with "#"
or "_"
depending on whether that element is an element of a second list. We can split that into two parts. The first part, "Replace each element in a list with the result of calling a function with that element as its argument" is map
. The second, doing something based on whether an item is an element of a list, does indeed use elem
. So we will
map
over a list and- call
elem
on each element, - comparing it with the list of known coordinates, and
- decide which string to replace the element of the list with based on the result of the call to
elem
.
getHash known xs = map (\x -> if x `elem` known then "#" else "_") xs
Now, why did I give the known list first? It's mostly personal preference, but I think it works a bit better with partial application. getHash [(1,2)]
is a function that compares a list given as an argument with a static 'known' list. And since xs
is the right position for it, we can also use eta reduction in the definition:
getHash known = map (\x -> if x `elem` known then "#" else "_")