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



所以,我定义了一个数据类型,看起来像这样:

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)

代码本身毫无意义,但让我恼火的是,我甚至无法运行它。无论我如何格式化上面的内容,我似乎总是会遇到语法错误。有人能指引我朝正确的方向走吗?

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

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 = ...
...

最新更新