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 uncurry
ing 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.