为什么我不能在Haskell中的连接函数(++)上进行模式匹配?

时间:2015-12-11 06:38:52

标签: haskell pattern-matching

我正在尝试在函数Split中匹配**String Newline String**模式。

split::String -> [String]
split[] = []
split (x++'\n':xs) = [x]++split(xs)

我收到此错误: Parse error in pattern: x ++ ('\n' : xs)

我在这里做错了什么?

我知道还有其他方法可以达到相同的结果,但我想了解这种模式有什么问题。我是Haskell BTW的新手。

2 个答案:

答案 0 :(得分:12)

一个问题(据我所知)是++不是:方式的列表数据类型的构造函数。您可以将列表数据类型视为

data [a] = [] | a : [a]

其中:是将元素附加到列表前面的构造函数。但是,++是一个函数(在此处的文档中定义:http://hackage.haskell.org/package/base-4.8.1.0/docs/src/GHC.Base.html#%2B%2B)为

(++) :: [a] -> [a] -> [a]
(++) []     ys = ys
(++) (x:xs) ys = x : xs ++ ys

我们可以定义我们自己的数据类型列表,如

data List a = Empty | Cons a (List a)

这将模仿我们熟悉的列表的行为。实际上,您可以在模式中使用(Cons val)。我相信你也可以定义一个带有concat构造函数的类型

data CList a = Empty | Cons a (CList a) | Concat (CList a) (CList a)

您可以使用它来懒洋洋地连接两个列表并将它们连接成一个列表。使用这样的数据类型,您可以将模式与Concat xs ys输入进行模式匹配,但是您只能在两个列表的边界上工作,而不是在一个列表的中间。

无论如何,我自己对Haskell还是比较新的,但我希望这是关键。

答案 1 :(得分:5)

想象一下你可以。然后匹配"a\nb\nc"可以生成x = "a", xs = "b\nc"x = "a\nb", xs = "c",您需要一些临时规则来决定使用哪个。一般来说,与函数匹配也是不可能合理地实现的:您需要找到x给定f x,除了尝试所有可能的x之外,没有办法做到这一点。