Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why is this lambda function a parse error with pattern matching and cons operator?

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!

like image 924
Mittenchops Avatar asked Jun 21 '26 01:06

Mittenchops


1 Answers

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.

like image 168
2 revs, 2 users 84%Will Ness Avatar answered Jun 22 '26 15:06

2 revs, 2 users 84%Will Ness