3 ms·
Haskell's record system (analogue of C's structs) has two major deficiencies. 1. Modifying a record value (that is, making a copy of a record value but with di
by mooism2 13y ago
Haskell's record system (analogue of C's structs) has two major deficiencies.
1. Modifying a record value (that is, making a copy of a record value but with different values in one or two of its fields) is unnecessarily complicated and uncomposable. This makes modifying a subfield painful.
2. Field names are in the global namespace. Thus you cannot have e.g. a field named `map` (conflicts with the standard `map` function); nor a local variable named `owner` in the same scope that you use a field named `owner`; nor may two different record types both have a `name` field. C had this problem in the 70s (which is why e.g. struct tm has tm_sec and tm_min fields instead of sec and min fields), but they solved it a long time ago.
The solution to deficiency 1 is to use lenses. Use the lens package from Hackage, but don't read its documentation at first: it generalises the problem exceedingly well, but this makes it harder to understand at first glance. Instead seek out a basic tutorial. At the cost of a short line of boilerplate for each record type, this works well.
There is no satisfactory solution to deficiency 2. Some people define each record type in its own module, and import each module qualified. I don't think this scales well. I prefer to put a record-type prefix on each of my field names (i.e. the same thing C programmers were forced to do in the 70s).
- pestaa 13y agoBoth are true, but I consider the second problem to be more like a trade off. In PHP I miss field extraction from an array so often; in Haskell it is just `map fieldName` and voila. Works just as well with namespaces -- I understand it does not scale when creating data types, but you normally don't import all of them at the same time into another module anyways.
- dllthomas 13y agoThat doesn't require them to be in the global namespace.
- tcsavage 13y agoThere's currently a Google summer of code project implementing overloaded record fields (http://www.google-melange.com/gsoc/project/google/gsoc2013/adamgundry/23001 http://www.google-melange.com/gsoc/project/google/gsoc2013/a...) - which should kinda solve problem 2. You still wouldn't be able to define a field `map` for the same reasons you stated, but you would be able to have multiple record types sharing the same field names.