Сопоставление с образцом в типе данных, содержащем список - PullRequest
0 голосов
/ 09 ноября 2018

Итак, я определил тип данных, который выглядит примерно так:

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 голосов
/ 09 ноября 2018

В выражениях и шаблонах : имеет более низкий приоритет, чем тип приложения. Следовательно, этот вид шаблона:

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