|
|
|
# read only constructors
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
when you export a data constructor, you export not only the ability to pattern match with said constructor, but also to create new values with that constructor. This can be harmful to abstract data types that want to make use of memoizing constructor or enforce invarients on a data type with constructor functions.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
An example would be
|
|
|
|
|
|
|
|
|
|
|
|
```wiki
|
|
|
|
|
|
|
|
data Term = LetRec {
|
| ... | ... | @@ -24,8 +27,10 @@ and only created if they are actually needed but also shared if they are |
|
|
|
needed again for the same type.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
we can create a constructor to enforce this like so
|
|
|
|
|
|
|
|
|
|
|
|
```wiki
|
|
|
|
letRec :: [(Name,Term)] -> Term -> Term
|
|
|
|
letRec defns body = LetRec {
|
| ... | ... | @@ -40,11 +45,14 @@ and that is good, but we cannot prevent people from getting around our |
|
|
|
constructor function without also blocking the very useful ability to pattern
|
|
|
|
match on Terms.
|
|
|
|
|
|
|
|
|
|
|
|
## proposal
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
allow data consructors to be exported and imported readonly
|
|
|
|
|
|
|
|
|
|
|
|
```wiki
|
|
|
|
|
|
|
|
module Foo(bar,Foo(readonly Bar, Baz)) where
|
| ... | ... | @@ -61,11 +69,5 @@ bar i = Bar i (i*2) |
|
|
|
|
|
|
|
|
|
|
|
we might want to reused the 'closed' keyword from the [ClosedClasses](closed-classes) proposal.
|
|
|
|
see also the abstraction section in [ExistingRecords](existing-records).
|
|
|
|
|
|
|
|
## Comment
|
|
|
|
|
|
|
|
|
|
|
|
This is related to [Views](views) and [PatternSynonyms](pattern-synonyms). There is definitely scope for improvement
|
|
|
|
in this area, but somehow I think there should be a unified, more comprehensive story. This seems,
|
|
|
|
to me, to be too much of a stop-gap measure. |