为什么此lambda函数具有模式匹配和cons运算符的解析错误?

时间:2019-04-13 21:19:46

标签: parsing haskell

我正在尝试从列表列表中解析记录(从this question继续)。

这是我的记录

data Record = Record Text Text Text Text Text Text Text Text Text deriving (Show, Generic)

此语法有效:

parseRecords :: [[Text]] -> [Record]
parseRecords = map (\[f1,f2,f3,f4,f5,f6,f7,f8,f9,_] -> Record f1 f2 f3 f4 f5 f6 f7 f8 f9)

此语法检查,但已将我固定为10个参数。我宁愿能够拥有更多的东西,并通过将它们匹配到一个我不会传递的[_]列表中的模式来忽略更大的那些。我尝试了以下方法:

parseRecords = map (\f1:f2:f3:f4:f5:f6:f7:f8:f9:[_] -> Record f1 f2 f3 f4 f5 f6 f7 f8 f9)

但是,此操作失败:

Parse error (line 27, column 24): parse error on input ‘:’

我可能发誓我以前见过lambda中使用的这种模式匹配。我不知道我的冒号运算符是解析错误吗?很难质疑出了什么问题。

谢谢!

1 个答案:

答案 0 :(得分:3)

就像您需要在函数绑定中的模式周围加上括号一样,

f (x:xs) = ...

您需要在lambda中的模式周围加上括号:

parseRecords = map (\ (f1:f2:f3:f4:f5:f6:f7:f8:f9:_) -> Record f1 f2 f3 f4 f5 f6 f7 f8 f9)
                      -------pattern----------------
                   ------------------lambda function--------------------------------------

有时可以省略括号,但并非总是如此。列表模式为:

[]           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 ......

这是因为:与右边相关,所以(x:y:xs)实际上是(x:(y:xs))

最后,_是通配符。它就像xyxs之类的变量模式,但没有名称。每个_都彼此不同,就好像它是用唯一的名字命名的,尽管缺少了一样。