1

Is there a benefit to specifically reserving varied data-type pairings for tuples like such:

[(23, "Jordan"), (8, "Bryant")]

As opposed to just using a two-dimensional list:

[[23, "Jordan"], [8, "Bryant"]]

I know the second piece of code will not work in Haskell

duplode
  • 33,731
  • 7
  • 79
  • 150
Kevin Behan
  • 486
  • 5
  • 20
  • 4
    Lists must contain all the same type. If you want multiple types, that's what tuples are for. Tuples also keep the length fixed, which may be important sometimes. Lists don't. – Neil Forrester Jul 19 '15 at 02:40
  • That's not entirely true, or maybe I'm misunderstanding you, because you can pass a list a group of tuples, so in a sense a list can accept multiple types. – Kevin Behan Jul 19 '15 at 02:42
  • 3
    Each element of the list will be a tuple. Each of those tuples will contain the same number and types of elements. – Neil Forrester Jul 19 '15 at 02:53
  • Of course, my thought is that logic, to an extent, defeats the purpose of a tuple-- I could be wrong. I think that lists are sufficient enough to create that same kind of functionality, maybe they aren't. – Kevin Behan Jul 19 '15 at 04:33
  • 4
    Tuples are fixed length but can mix types. Lists have arbitrary length but only contain elements of a single type. – Daniel Wagner Jul 19 '15 at 04:38
  • 1
    many untyped counterparts to staticay typed constructs are "sufficient enough" for the same functionality, even Assembly is, so that argument is a tautology and doesn't suggest you should use untyped or less typed constructs if you've chosen a language that builds heavily on its static type system, such as Haskell. – Erik Kaplun Jul 19 '15 at 08:27
  • 1
    possible duplicate of [Is there a difference between a list and a tuple?](http://stackoverflow.com/questions/30518013/is-there-a-difference-between-a-list-and-a-tuple) – Erik Kaplun Jul 19 '15 at 08:35
  • Why ask this question at all if you know full well that the second example won't work? You've answered your own question. – AJF Jul 19 '15 at 10:02
  • 1
    Relevant as well, even though it's a Python question: [What's the difference between list and tuples?](http://stackoverflow.com/questions/626759/whats-the-difference-between-list-and-tuples?rq=1) Key quote: "Tuples have structure, lists have order." – duplode Jul 19 '15 at 16:58

3 Answers3

3

Why do we use tuples, if we can use a two dimensional list?

Because lists and tuples are conceptually different things, and the type system gives us an useful way to state and recognise the difference in code. For one of many possible examples, one might define...

type ListyPair a = [a]

... and then...

listyFst :: ListyPair a -> a
listyFst [x, _] = x

listySnd :: ListyPair a -> a
listySnd [_, y] = y

... so that:

GHCi> listyFst [3,4]
3
GHCi> listySnd [3,4]
4

But what happens if the listy "pair" has just one element, or none? We would have to throw a runtime error (yuck), or make listyFst and listySnd result in a Maybe a so that we can handle failure cleanly. What if the "pair" has more than two elements? Should we just discard them silently, or would it be better to make the functions fail in this case as well?

From the perspective of a strong type system user, when we replace an actual pair with ListyPair we are throwing away useful information. Knowing that there are really just two elements allows us to avoid all of the complications above.

realFst :: (a, b) -> a
realFst (x, _) = x

realSnd :: (a, b) -> b
realSnd (_, y) = y 
duplode
  • 33,731
  • 7
  • 79
  • 150
1

"Is there a benefit to specifically reserving varied data-type pairings for tuples like such:"

Yes. The benefits to the use of tuples are related to the usage patterns around the data and any performance requirements.

Tuples are often immutable and have a predictable size.

Since you're writing a haskell program, your lists of "strings and integers" are actually a list of a union type (call it whatever you want)... your tuple is just a special case.

This point is a bit more clear if you think about this as python code. (Both strings you provide are valid python code; I originally thought the question was python related)

In python, you would prefer the List of Tuples if you knew that the tuples had a fixed (or predictable) structure.

That would let you write code like:

[ print(name) for jersey, name in list_of_tuples ]  

You would choose to use the tuple if you believed that paying for the price of an object representation wasn't worth it, and you preferred expressing every tuple reference with an unpacking.

Fortunately, since you're writing haskell, you have a number of tools to model and represent problems strongly in the type system. I think if you take a bit more time to read up and write some haskell (Learn you a Haskell for Great Good is a great book), you'll have a better understanding of the type system and you'll find the answer for this yourself.

If you're looking to learn more about functional programming in general, The Little Schemer is also spectacular.

((un)Fortunately, in python you can write code that handles both types of data structures, instead of worrying about the types going into the code. Haskell requires you to think a bit differently than that.)

Tom White
  • 27
  • 2
  • It's funny you mention "Learn you a Haskell for Great Good" as I've already read it, and my question was inspired by that book; I didn't think they explained this dilemma properly or thoroughly enough. Great book by the way! – Kevin Behan Jul 19 '15 at 04:31
  • I'm going to look into "The Little Schemer" though thank you for the suggestion! It's much appreciated! – Kevin Behan Jul 19 '15 at 04:52
  • 1
    lists are also immutable in Haskell; you should never put side effectful expressions in a list comprehension in Python; this is an answer largely about Python to a question solely about Haskell so -1. – Erik Kaplun Jul 19 '15 at 08:28
  • @ErikAllik Thanks for your feedback! I just noticed this when I was puzzling over some odd emails from stack overflow. (Apparently I got upvoted.) Yeah, I agree that I had a bit too much python focus; but this is clearly a type system question; and type systems are hard. :( I typed this into ghci and it worked fine. Prelude> let it_be = [("Whatever", 0), ("The", 1) , ("Fun", 3), ("you", 4), ("want", 5)]; If I wipe away the let it's python. If I type it wrong in haskell, it feels GOOD Prelude> let it_be = [("a", 0), ("bit different on", 1), ("stack","overflow")]; Will error as we expect. – Tom White Aug 13 '15 at 23:43
1

This question should have probably been more clearly stated as:

Why must we insist on the definition of a list as a collection of elements of exactly one type?

From one point of view the answer could be that it allows us to reason about lists in a rigorous way and a whole new class of operations become possible. Ex. how else would you define map for lists?

From another point of view, if lists could hold multple types then the language could not have been staticly typed. Ex. if you are passed a list as an argument what is the type of head element?

You don't have this problem with tuples because you define the type of each element a priori and the length is fixed.

Is there a benefit to specifically reserving varied data-type pairings for tuples...

It is absolutely necessary for a statically typed language that lists hold elements of exactly one type, so the question of benefit has no benefit.

user2847643
  • 2,893
  • 14
  • 22