Record types with multiple constructors

Hi, Record types usually have a single constructor. I've even seen blog posts that suggest that they must have a single constructor. However, multiple constructors are allowed: data Employee = RegularEmployee { name :: String } | Supervisor { name :: String, salesTarget :: Double } Manager { name :: String, salesTarget :: Double budget :: Double } I don't see this used much in Haskell code - either in explanatory books/tutorials or in code I've examined on GitHub. Are there drawbacks to using multiple constructors in this way? Derek.

Yes: it becomes really easy to write partial/broken programs, e.g.: let myEmployee = RegularEmployee "Alice" ... supervisor = myEmployee { salesTarget = 5.4 } If you want to have both multiple constructors *and* multiple fields per constructor, I'd recommend one of the following: 1. Don't name the fields. 2. Use another type in between that has only one constructor, e.g. `data Supervisor = Supervisor { name :: String, salesTarget :: Double }`. A great example of this is the Node datatype[1] from xml-types. [1] http://www.stackage.org/haddock/2014-11-27-ghc78-exc-1/xml-types-0.3.4/Data-... On Sun Dec 07 2014 at 11:37:16 AM Derek McLoughlin < derek.mcloughlin@gmail.com> wrote:
Hi,
Record types usually have a single constructor. I've even seen blog posts that suggest that they must have a single constructor. However, multiple constructors are allowed:
data Employee = RegularEmployee { name :: String } | Supervisor { name :: String, salesTarget :: Double } Manager { name :: String, salesTarget :: Double budget :: Double }
I don't see this used much in Haskell code - either in explanatory books/tutorials or in code I've examined on GitHub. Are there drawbacks to using multiple constructors in this way?
Derek. _______________________________________________ Beginners mailing list Beginners@haskell.org http://www.haskell.org/mailman/listinfo/beginners

Absolutely!
Any record fields not defined for all constructors become partial.
The correct way would be to have each constructor take a distinct type (if
they are indeed distinct). Unfortunately this isn't nearly as succinct, but
it is much safer.
- Lyndon
On Sun, Dec 7, 2014 at 8:37 PM, Derek McLoughlin wrote: Hi, Record types usually have a single constructor. I've even seen blog
posts that suggest that they must have a single constructor. However,
multiple constructors are allowed: data Employee = RegularEmployee {
name :: String
} |
Supervisor {
name :: String,
salesTarget :: Double
}
Manager {
name :: String,
salesTarget :: Double
budget :: Double
} I don't see this used much in Haskell code - either in explanatory
books/tutorials or in code I've examined on GitHub. Are there
drawbacks to using multiple constructors in this way? Derek.
_______________________________________________
Beginners mailing list
Beginners@haskell.org
http://www.haskell.org/mailman/listinfo/beginners

On Sun, Dec 07, 2014 at 09:37:11AM +0000, Derek McLoughlin wrote:
Hi,
Record types usually have a single constructor. I've even seen blog posts that suggest that they must have a single constructor. However, multiple constructors are allowed:
data Employee = RegularEmployee { name :: String } | Supervisor { name :: String, salesTarget :: Double } Manager { name :: String, salesTarget :: Double budget :: Double }
I don't see this used much in Haskell code - either in explanatory books/tutorials or in code I've examined on GitHub. Are there drawbacks to using multiple constructors in this way?
I think you might see it fairly frequently in users of command line parser libs, e.g. optparse-applicative[^1], for accepting sub-commands. /M [^1]: http://hackage.haskell.org/package/optparse-applicative -- Magnus Therning OpenPGP: 0xAB4DFBA4 email: magnus@therning.org jabber: magnus@therning.org twitter: magthe http://therning.org/magnus Perl is another example of filling a tiny, short-term need, and then being a real problem in the longer term. -- Alan Kay
participants (4)
-
Derek McLoughlin
-
Lyndon Maydwell
-
Magnus Therning
-
Michael Snoyman