I am reading a tutorial that uses the following example (that I’ll generalize somewhat):
f :: Foo -> (Int, Foo) ... fList :: Foo -> [Int] fList foo = x : fList bar where (x, bar) = f foo
My question lies in the fact that it seems you can refer to x and bar, by name, outside of the tuple where they are obtained. This would seem to act like destructuring parameter lists in other languages, if my guess is correct. (In other words, I didn’t have to do the following:)
fList foo = (fst tuple) : fList (snd tuple) where tuple = f foo
Am I right about this behavior? I’ve never seen it mentioned yet in the tutorials/books I’ve been reading. Can someone point me to more info on the subject?
Edit: Can anything (lists, arrays, etc.) be destructured in a similar way, or can you only do this with tuples?
Seeing your edit, I think what your asking about is Pattern matching.
And to answer your question: Yes, anything you can construct, you can also ‘deconstruct’ using the constructors. For example, you’re probably familiar with this form of pattern matching:
However, there are more places where you can use pattern matching, other valid notations are:
Note that the last two examples are a bit different from the first to because they give different error messages when you call them with an empty list.
Although these examples are specific to lists, you can do the same with other data types, like so:
Again, the last function will also crash if you call it with
Nothing.To sum up; if you can create something using constructors (like
(:)and[]for lists, or(,)for tuples, orNothingandJustfor Maybe), you can use those same constructors to do pattern matching in a variety of ways.