Brian Huffman wrote:
Hello all,
In Haskell, when I declare the following type:
data Foo = MkFoo (Int, Bool)
the constructor "MkFoo" has a run-time cost: A pointer must be dereferenced whenever I pattern-match on MkFoo, and memory is allocated when I apply the MkFoo constructor.
On the other hand, if I declare this type:
newtype Foo = MkFoo (Int, Bool)
then the MkFoo constructor has no existence at run-time: Types Foo and (Int, Bool) have the same representation on the heap, and the MkFoo constructor function is a no-op.
Here's my question: When I declare a single-constructor datatype in Poly/ML, is it more like Haskell's "data" or "newtype"?
In Poly/ML a single constructor is the identity function so the answer is presumably that it's like "newtype" (I don't know Haskell).
Here's the reason I'm asking: I'm thinking of using single-constructor datatypes to implement abstract types, by defining the datatype within the module, but not including the constructor function in the module signature. (This is exactly how people usually do abstract types in Haskell - just don't export the constructors.) I'd like to know if there are any pros or cons of this method compared to using abstype.
There's no difference in implementation between an abstype and a datatype. "abstype" is a very old construction in Standard ML and predates the modules system let alone the opaque signature matching of ML 97. It's probably better on stylistic grounds to use signature matching to hide the constructors but I don't think there's any difference in the underlying implementation.
David