Template Haskell lets you reify supposedly-abstract data types
Serguey Zefirov writes (on Haskell cafe) "Data.Map.Map and Data.Set.Set are exported abstractly, without exposing knowledge about their internal structure.
I cannot directly create my own class instances for them because of that. But I found that I can write Template Haskell code that could do that - those data types could be reified just fine."
Good point. It's not quite clear what a better design should be. Haskell controls data abstraction by whether or not the constructors of the data type are exported. But they might be exported by the module that defined them, but not to "clients" of the data type. So the data type is abstract to some importers but concrete to others.
So when should TH let you reify the representation of a data type? Maybe it should let you do so iff
- The data constructors of the data type are in scope (somehow) at the reification site
So, to take an example:
module Conc( T(..), Blah(..) ) where
data T = T1 | T2 Blah
data Blah = A | B
module Abs( T, Blah ) where
import Conc
module ReifyA where
import Abs
foo = reify ''T
module ReifyC where
import Conc
foo = reify ''T
So the reify
in ReifyC.foo
would "see" the data constructors of T
, but not the one in ReifyA
.
But this approach raises related questions.
- What if some, but not all, of
T
's data constructors are in scope? - What if the data constructors are all in scope, but some mention a type that is not in scope? For example, suppose type
Blah
is not in scope, but you reifyT
? - At the moment, when you reify a data type you get its
Dec
. But ifT
is abstract, whatDec
can we give it? Just giving it an empty constructor list seems wrong; after all, it might really be a zero-constructor data type. I suspect we may want a richer data type forInfo
(ie whatreify
returns).
All these require design thinking. Does anyone want to lead that debate? Otherwise things will probably stay as they are.
I've labelled this as a feature request, although it is a kind of bug, because of this design component.
Trac metadata
Trac field | Value |
---|---|
Version | 6.12.3 |
Type | FeatureRequest |
TypeOfFailure | OtherFailure |
Priority | normal |
Resolution | Unresolved |
Component | Compiler |
Test case | |
Differential revisions | |
BlockedBy | |
Related | |
Blocking | |
CC | sergueyz@gmail.com |
Operating system | |
Architecture |