5 ms·
Practical Benefits of the Haskell Type System
- AnimalMuppet 11y agoA bit off topic, but this seems like as good a place to ask this as any I've seen lately. Is it just me, or is there a huge hole in Haskell's type systems around dictionaries and tuples? If I understand correctly, if you want to do something like a C/C++ struct (a collection of data fields, not a class with some behavior), then in Haskell, you either make it a dictionary with string keys, or you make it a tuple. But if you pass either of those to a function, don't you lose type safety? Let's say that I have a structure that represents a person. It's got a first name (string), a last name (string), and an age (non-negative integer). I create a tuple (first, last, age), or I create a dictionary ("first" : first, "last" : last, "age" : age). (The syntax there is lousy, I don't know how Haskell has you assemble a dictionary. It's intended to be read as ("key" : value) entries.) My function can require that it gets passed a tuple. I suspect that it can require that it gets passed a tuple with three items. But can it require that it gets passed a tuple that is (string, string, integer)? Worse, can it require that it gets passed a tuple that is (first, last, age) and not (city, state, zip code)? Dictionaries are even worse. The function may be able to require that it gets passed a dictionary with three entries. But can it guarantee that it gets passed a dictionary with a "first" key, and that the value of that key is a string? So it seems to me that C/C++ in this area can give you stronger type safety than Haskell, because a function can guarantee that it got passed a Person struct, which has a string first, and a string last, and an int age, and that it did not get called with anything else. Or am I all wet, and only an idiot would try to do structs that way in Haskell?
- samungo 11y agoYes that would be a bad way to do structs in Haskell. Instead you would simply use Haskell's record syntax, ie. data Person = Person { firstName :: String, lastName :: String, age :: Int } You could also easily define more specific types like for example: type Age = Int, which should prevent somebody from creating a person where they use a zip code for that person's age.
- mightybyte 11y agoI'll second this comment. No self respecting Haskell programmer would use the tuple or dictionary scheme described. This is exactly how you'd expect to see it done in Haskell. data Person = Person { firstName :: String , lastName :: String , age :: Int } The compiler automatically creates the following functions for you. Person :: String -> String -> Int -> Person firstName :: Person -> String lastName :: Person -> String age :: Person -> Int So you get all the expected type safety. The nice thing is that since this syntax is very light, you end up creating all kinds of small types here and there for better type safety. Whenever I find myself using tuples of more than 3 or so items, I'll frequently create a new type for it. This serves as better documentation and makes the code easier to refactor.
- gizmo686 11y agoTuples are defiantly a shortcomming in Haskell's type system, although not for the reason you describe. The type of a tuple, is defined by the number of entries, and the types of those entries, so it can guarantee that it is getting passed a tuple that is (string, string, integer). If you want to guarantee that you are getting passed a tuple that is (first, last, age), then you would want to define new types that are dedicated to first names, last names, and age respectively. However, this is no different than what you would have to do to make this guarantee if you passed them in as curried arguments instead of a tuple. The main type system weakness of tuples, is that their is no way to write a generic tuple function. For example, if you want to write a function to return the first element of a tuple, you need to encode into the type of that function the number of elements in the tuple. In your dictionary example, use the "data" keyword to define a new type. Unless age is the same type as first and last, you cannot (easily) even create the dictionary you describe.