Record types with multiple constructors

Previous Topic Next Topic
 
classic Classic list List threaded Threaded
4 messages Options
Reply | Threaded
Open this post in threaded view
|

Record types with multiple constructors

Derek McLoughlin
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.

Reply | Threaded
Open this post in threaded view
|

Record types with multiple constructors

Michael Snoyman
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-XML-Types.html#t:Node

On Sun Dec 07 2014 at 11:37:16 AM Derek McLoughlin <
derek.mcloughlin at 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 at haskell.org
> http://www.haskell.org/mailman/listinfo/beginners
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://www.haskell.org/pipermail/beginners/attachments/20141207/030625db/attachment.html>

Reply | Threaded
Open this post in threaded view
|

Record types with multiple constructors

Lyndon Maydwell
In reply to this post by Derek McLoughlin
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 <derek.mcloughlin at 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 at haskell.org
> http://www.haskell.org/mailman/listinfo/beginners
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://www.haskell.org/pipermail/beginners/attachments/20141207/3ae25ab3/attachment.html>

Reply | Threaded
Open this post in threaded view
|

Record types with multiple constructors

Magnus Therning
In reply to this post by Derek McLoughlin
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 at therning.org   jabber: magnus at 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
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 181 bytes
Desc: not available
URL: <http://www.haskell.org/pipermail/beginners/attachments/20141207/6ea86e09/attachment.sig>