4 ms·
The point is that you use a single function for any type. So in Python you'd have to do int() or float() or customType()... In Haskell, all of these would be ju
by tikhonj 14y ago
The point is that you use a single function for any type. So in Python you'd have to do int() or float() or customType()... In Haskell, all of these would be just `read'. The type system can figure out which instance to use for you, without having to specify it. Moreover, it's also trivial to write a function that works on any readable type, something hard (although not entirely impossible) to do in Python.
This makes it much easier to use: whenever you want to get any type from a string, you just read it. This is just like being able to print values of any type, except for parsing.
This can also be used with constants rather than functions. So maxBound is the maximum value for any bounded type. In Python, the closest you can get to that is something like float.maxBound. (Except, apparently, it's actually sys.float_info.max.)
As I mentioned, this also lets you define new numeric types that can still use the same literals. For my most recent project, I needed 18-bit words. I could do this and still write expressions like `x + 1` using the Word18 type. Moreover, it would be very easy to make my code generic over the exact type of number used--this would make it possible to use numbers of different sizes or even something more exotic like random variables. (It happens to be tricky because some of the semantics I was working with rely on having exactly 18 bits, but that's an issue with the domain and not with Haskell.)
In another language, I would either have to use the normal int type and make sure to always keep track of the overflow myself or I would have to wrap every literal in a function that turned into an 18-bit word.
So the special quality is being able to dispatch on the return type of an expression rather than on the types of the arguments. I think this is very special indeed and extremely useful. I hope this clarifies everything.
- SilasX 14y agoThat does make more sense, and I appreciate the more thorough explanation. It seems a bit ironic though, that Python makes you more specific and certain about the output type than Haskell!
- Peaker 14y agoIt is only ironic until you realize static typing can often save you from writing code, and not just require more code.
- SilasX 14y agoIn general, sure. Doesn't change that the "read" function seems to break the spirit of that.
- Peaker 14y agoHow so? Inferring which implementation of "read" to use based on the types is exactly the same spirit of inferring which implementation of "length" to use. Haskell can maintain consistency in both, but dynamically typed languages must revert to explicitly choosing the implementation in the former.
- SilasX 14y agoYes, it goes nicely with that spirit. But it doesn't go nicely with "have a well-specified return type for all functions that you know in advance", as "read" can return anything. It's great for languages to pick the right implementation of "length" on the fly, but the point is, they all return integers. "read"? Who knows what type you'll get back in Haskell, the "you must specify [or at least plan out the] output type" language? There, it seems to break the trend.
- Peaker 14y agoRead in Haskell returns a well defined type, it just happens to be polymorphic.
- SilasX 14y agoBy that broad a definition of "a well defined polymorphic type", so does every function in every language, at least those that can say "everything's an object/function/data/etc!"
- Peaker 14y agothe type is statically checked, not dynamically checked. Unlike something that just returns an unknown existential "object" type.