对包含列表的数据类型进行模式匹配

时间:2018-11-09 03:28:25

标签: list haskell nested pattern-matching

因此,我定义了一种类似于以下内容的数据类型:

data SumCoolElement = Int
newtype DType = D [SumCoolElement]

我想遍历SumCoolElements,我正在尝试使用以下代码:

iterator :: Dtype -> DType -> Int
iterator (D lst1) (D lst2) = case (x:xs) (y:ys) of
  (D fstint:xs) [] -> fstint
  (D fstint:xs) (D sndint:ys) | fstint > sndint -> iterator (D (fstint + sndint) : xs) (D ys)
  (D fstint:xs) (D sndint:ys) | fstint < sndint -> iterator (D (fstint - sndint) : xs) (D ys)

代码本身是毫无意义的,但令我烦恼的是,我什至无法运行它。无论我如何格式化以上内容,我似乎总是遇到语法错误。有人可以指导我正确的方向吗?

1 个答案:

答案 0 :(得分:3)

在表达式和模式中,:的优先级低于类型应用程序。因此,这种模式:

f (D x:xs) = ...

将被解析为:

f ((D x):xs) = ...

这是不正确的。您要明确指定:

f (D (x:xs)) = ...

或者在您的特定情况下:

(D (fstint:xs)) [] -> ...
(D (fstint:xs)) (D (sndint:ys)) | fstint > sndint -> ...
  ...

这些表达式的右侧存在相同的问题:

D (fstint + sndint) : xs

将解析为:

(D fstint + sndint) : xs

应该是:

D (fstint + sndint : xs)

最后,还必须使用@ assembly.jc的其他答案来修复它-case表达式的参数具有未定义的变量。您可能会说(x:xs)lst1,而(y:ys)lst2,但是请注意,由于第二个列表可能为空,因此直接进行模式匹配会更容易:

iterator :: Dtype -> Dtype -> Int
iterator (D fstint:xs) [] = fstint
iterator (D fstint:xs) (D sndint:ys) | fstint > sndint = ...
...