I am trying to parse a record from a lists of lists (continuing from this question).
Here's my record
data Record = Record Text Text Text Text Text Text Text Text Text deriving (Show, Generic)
This syntax works:
parseRecords :: [[Text]] -> [Record]
parseRecords = map (\[f1,f2,f3,f4,f5,f6,f7,f8,f9,_] -> Record f1 f2 f3 f4 f5 f6 f7 f8 f9)
This syntax checks, but has me fixed at 10 parameters. I would rather be able to have more than that and ignore the ones greater by pattern matching them into a [_] list I will not pass along. I tried the following:
parseRecords = map (\f1:f2:f3:f4:f5:f6:f7:f8:f9:[_] -> Record f1 f2 f3 f4 f5 f6 f7 f8 f9)
This, however, fails with:
Parse error (line 27, column 24): parse error on input ‘:’
I could have sworn I saw this kind of pattern matching used in lambdas before. What am I missing that my colon operators are a parse error? It is hard to interrogate what's going wrong.
Thanks!
Just like you need parentheses around patterns in function bindings,
f (x:xs) = ...
you need parentheses around patterns in lambdas:
parseRecords = map (\ (f1:f2:f3:f4:f5:f6:f7:f8:f9:_) -> Record f1 f2 f3 f4 f5 f6 f7 f8 f9)
-------pattern----------------
------------------lambda function--------------------------------------
Sometimes parentheses can be omitted, but not always. The list patterns are:
[] matches []
(x:xs) matches [x, ...] so that (x:xs) == [x] ++ xs
(x:y:xs) matches [x, y, ...] so that (x:y:xs) == [x] ++ (y:xs)
== [x,y] ++ xs
..... and so on ......
This is because : associates to the right, so (x:y:xs) is actually (x:(y:xs)).
Lastly, _ is a wildcard. It is like a variable pattern like x or y or xs, but without a name. Each _ is different from another, as if it was named with a unique, though missing, name.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With