[Haskell-cafe] Mapping Haskell Concepts To C# 3
Brandon S. Allbery KF8NH
allbery at ece.cmu.edu
Sun May 18 10:55:33 EDT 2008
On 2008 May 18, at 9:59, Kaveh Shahbazian wrote:
> For something like: type Thing a b = ThisWay a | ThatWay b | NoWay
> actually there is no equivalents for data constructor
I presume you mean "data" instead of "type". Not that I can address
your question directly, as I don't know C#. In C it's a union; in C++
you would export constructors ThisWay(), ThatWay(), NoWay() from class
Thing. I presume C# is similar. Haskell syntax is decidedly more
compact than any of them.
> in C# 3 (I think). I asked it if there are other ideas about this:
> Controlling the execution path by deciding based of structure of
> data with a trick other than reflecting!
in C-like languages, the class includes a structure tag which is set
by the constructor. Guess what? That's how Haskell does it, just
implicitly (hence, again, nicely compact syntax). (You can actually
experiment with this in GHC; using internal stuff like UnsafeCoerce#
you can coerce one datum to another if they have the same (0-based,
assigned in order of definition) constructor tag and the same
representation for the data value. IIRC in GHC the internal
constructor tag is an 8-bit unsigned value.)
To make the above a bit clearer (I hope), here's a rough C
approximation of a simple Haskell type:
/* data Foo = FooInt Int | FooDouble Double */
struct Foo {
unsigned char _FooTag;
union {
#define _FooTag_FooInt 0
int _FooInt;
#define _FooTag_FooDouble 1
double _FooDouble;
} _Foo_u;
};
/* here I assume unboxed basic types for simplicity */
struct Foo *FooInt(int param) {
Foo *foo = malloc(sizeof *foo); /* assume sane error checking
here */
foo->_FooTag = _FooTag_FooInt;
foo->_Foo_u._FooInt = param;
}
struct Foo *FooDouble(int param) {
Foo *foo = malloc(sizeof *foo); /* assume sane error checking
here */
foo->_FooTag = _FooTag_FooDouble;
foo->_Foo_u._FooDouble = param;
}
/*
* bar (FooInt i) = ...
* desugars to
* bar x = case x of { FooInt i -> ... }
* which is very roughly (pretend I catch x == 0 and invoke
error("Undefined"))
* bar(Foo x) { switch (x->_FooTag) { case _FooTag_FooInt: i =
x->_Foo_u._FooInt; ... } }
*/
--
brandon s. allbery [solaris,freebsd,perl,pugs,haskell] allbery at kf8nh.com
system administrator [openafs,heimdal,too many hats] allbery at ece.cmu.edu
electrical and computer engineering, carnegie mellon university KF8NH
-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://www.haskell.org/pipermail/haskell-cafe/attachments/20080518/abc5e03c/attachment.htm
More information about the Haskell-Cafe
mailing list