3

I found this code that builds a list corresponding to the Thue-Morse sequence:

thueMorse :: [Int]
thueMorse = 0 : interleave (map (1-) thueMorse) (tail thueMorse)
    where interleave (x:xs) ys = x : interleave ys xs

It's perfect and works wonders, but I cannot wrap my head around it. An example:

> take 8 thueMorse 
[0,1,1,0,1,0,0,1]

If I define the interleave function globally and use it I get, and rightly so, an exception:

> let interleave (x:xs) ys = x : interleave ys xs
> interleave [1,2,3] [4,5,6]
[1,4,2,5,3,6*** Exception: <interactive>:29:5-47: Non-exhaustive patterns in function interleave

So, how does the above work? Is it because it's an infinite list so it's safe to interleave forever?

2 Answers 2

7

Yes, it works because the input is a pair of infinite lists. That definition of interleave only handles the case where its first argument is not empty, ie uses the : constructor. But lists have a second constructor ([]) which that definition ignores is possible. A more complete definition would probably look like this, depending on how you want it to handle an empty input:

interleave (x:xs) ys = x : interleave ys xs
interleave [] ys = ys
Sign up to request clarification or add additional context in comments.

Comments

3

The exception already tells your error: your pattern for interleave isn't exhaustive. What happens if you try to use interleave [] a? The pattern for the first argument only matches lists with at least one element. That way, interleave is only defined partially, that is, not for all possible lists.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.