Home > Blockchain >  Filter along a list of tuples
Filter along a list of tuples

Time:12-07

I am trying to solve Day 4 of the Advent of Code and to do this I currently need to filter a list of list of tuples.

First of all, let's get the sample

sample=[[(2,4),(6,8)],[(2,3),(4,5)],[(5,7),(7,9)],[(2,8),(3,7)],[(6,6),(4,6)],[(2,6),(4,8)]]

This sample was obtained with Data.Text.splitOn and a simple tuple-ify function (\[x,y] -> (x,y)).

Then, we need to find all pairs of tuples where one contains the other. I, then, write the simple following helper

contains :: (Int,Int) -> (Int,Int) -> Bool
contains a b = (fst a) <= (fst b) && (snd a) <= (snd b)

Finally, I want to filter from the sample but I could not figure out how to do it. Of course, I reduce the 2D list of list of tuples to a simple 1D list of tuple with map;

main :: IO ()
main = do
  print $ length $ map solution sample

where, solution is either

solution :: [(Int,Int)] -> [Bool]
solution = filter (\x y -> x `contains` y || y `contains` x)

with the following error

Couldn't match type ‘(Int, Int)’ with ‘Bool’
      Expected: [(Int, Int)] -> [Bool]
        Actual: [(Int, Int)] -> [(Int, Int)]
    • In the expression:
        filter (\ x y -> x `contains` y || y `contains` x)

or

solution :: [(Int,Int)] -> [(Int,Int)]
solution = filter (\x y -> x `contains` y || y `contains` x)

with the following error

Couldn't match type ‘(Int, Int)’ with ‘Bool’
      Expected: [(Int, Int)] -> [Bool]
        Actual: [(Int, Int)] -> [(Int, Int)]
    • In the expression:
        filter (\ x y -> x `contains` y || y `contains` x)

or

solution :: [(Int,Int)] -> [(Int,Int)]
solution = filter (\[x,y] -> x `contains` y || y `contains` x)

with the following error

    • Couldn't match expected type: (Int, Int)
                  with actual type: [(Int, Int)]
    • In the pattern: [x, y]
      In the first argument of ‘filter’, namely
        ‘(\ [x, y] -> x `contains` y || y `contains` x)’
      In the expression:
        filter (\ [x, y] -> x `contains` y || y `contains` x)

etc...

I tried everything my learning brain could think of, and this is driving me crazy since the last couple of days. What am I doing wrong?

CodePudding user response:

I think your fundamental problem is your data representation. Your function contains takes exactly two tuples; that part's probably good. (It's a little unclear if your inequalities in its definition are correct, I don't have the context to know.) But the sample you've extracted contains items that are each lists of tuples; there's no guarantee of length.

I suggest re-working sample to have type [((Int, Int), (Int, Int))]. I think you'll be able to get it working from there; if you get stuck again you could try uncurrying contains (although you're already doing pattern matching, so you can probably ignore this).

CodePudding user response:

(\x y -> ...) is a lambda taking two parameters. You don't have that, you have a single tuple parameter.

(\[x, y] -> ...) is closer: it's a lambda taking one parameter, a list expected to have exactly two elements. But that's still not a two-tuple.

Instead, you want (\(x, y) -> ...), a lambda taking a two-tuple parameter.

  • Related