Home > database >  Haskell -- Substitute Elements In A List
Haskell -- Substitute Elements In A List

Time:11-11

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

  1. map over a list and
  2. call elem on each element,
  3. comparing it with the list of known coordinates, and
  4. 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 "_")
  • Related