|
|
# read only constructors
|
|
# 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.
|
|
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
|
|
An example would be
|
|
|
|
|
|
|
|
|
|
|
|
```wiki
|
|
```wiki
|
|
|
|
|
|
|
|
data Term = LetRec {
|
|
data Term = LetRec {
|
| ... | @@ -24,8 +27,10 @@ and only created if they are actually needed but also shared if they are |
... | @@ -24,8 +27,10 @@ and only created if they are actually needed but also shared if they are |
|
|
needed again for the same type.
|
|
needed again for the same type.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
we can create a constructor to enforce this like so
|
|
we can create a constructor to enforce this like so
|
|
|
|
|
|
|
|
|
|
|
|
```wiki
|
|
```wiki
|
|
|
letRec :: [(Name,Term)] -> Term -> Term
|
|
letRec :: [(Name,Term)] -> Term -> Term
|
|
|
letRec defns body = LetRec {
|
|
letRec defns body = LetRec {
|
| ... | @@ -40,11 +45,14 @@ and that is good, but we cannot prevent people from getting around our |
... | @@ -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
|
|
constructor function without also blocking the very useful ability to pattern
|
|
|
match on Terms.
|
|
match on Terms.
|
|
|
|
|
|
|
|
|
|
|
|
## proposal
|
|
## proposal
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
allow data consructors to be exported and imported readonly
|
|
allow data consructors to be exported and imported readonly
|
|
|
|
|
|
|
|
|
|
|
|
```wiki
|
|
```wiki
|
|
|
|
|
|
|
|
module Foo(bar,Foo(readonly Bar, Baz)) where
|
|
module Foo(bar,Foo(readonly Bar, Baz)) where
|
| ... | @@ -61,11 +69,5 @@ bar i = Bar i (i*2) |
... | @@ -61,11 +69,5 @@ bar i = Bar i (i*2) |
|
|
|
|
|
|
|
|
|
|
|
|
we might want to reused the 'closed' keyword from the [ClosedClasses](closed-classes) proposal.
|
|
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. |
|
|