hellomatey27
hellomatey27

Reputation: 115

Pattern matching on a datatype containing a list

So, I have defined a data type which looks something like this:

data SumCoolElement = Int
newtype DType = D [SumCoolElement]

I want to iterate over SumCoolElements, which I am trying to do with this code:

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)

The code itself is pointless, but what annoys me is that I can't even get it to run. I seem to keep running into syntax errors no matter how I format the above. Can someone please guide me in the right direction?

Upvotes: 1

Views: 76

Answers (1)

Koterpillar
Koterpillar

Reputation: 8104

In expressions as well as patterns, : has lower priority than type application. Therefore, this kind of pattern:

f (D x:xs) = ...

will be parsed as:

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

which is incorrect. You want to specify explicitly:

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

Or in your particular case:

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

There is the same issue on the right side of those expressions:

D (fstint + sndint) : xs

Will be parsed as:

(D fstint + sndint) : xs

It should be:

D (fstint + sndint : xs)

Finally, the other answer by @assembly.jc is also required to fix it - the argument of the case expression has undefined variables. You probably meant to say that (x:xs) is lst1 and (y:ys) is lst2, but note that since the second list might be empty, it is easier to go pattern matching directly:

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

Upvotes: 3

Related Questions