Kaveh Shahbazian | 17 May 21:37

Mapping Haskell Concepts To C# 3

I have question on mapping some Haskell concepts to C# 3 ones. Maybe there are not any strict equivalents; yet it helps:

1 - What is the equivalent of "Type Constructor" in C#?
2 - What is the equivalent of "Data Constructor" in C#?
3 - What is the logical implementation of pattern matching in C#? (For example using structures with indicator fields or using interfaces and inheritance and dynamically dispatch in calling overloaded methods. Also this question contain a hidden one...GADTs!)

Best Regards

--
Kaveh Shahbazian
email: kaveh.shahbazian <at> gmail.com

_______________________________________________
Haskell-Cafe mailing list
Haskell-Cafe <at> haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe
Sebastian Sylvan | 17 May 21:51

Re: Mapping Haskell Concepts To C# 3



2008/5/17 Kaveh Shahbazian <kaveh.shahbazian <at> gmail.com>:
I have question on mapping some Haskell concepts to C# 3 ones. Maybe there are not any strict equivalents; yet it helps:

1 - What is the equivalent of "Type Constructor" in C#?

Class declaration. Generic ones. E.g. List<int>, is a type where the type constructor List has been applied to the type int.
 

2 - What is the equivalent of "Data Constructor" in C#?

Constructors, I guess.
 

3 - What is the logical implementation of pattern matching in C#? (For example using structures with indicator fields or using interfaces and inheritance and dynamically dispatch in calling overloaded methods. Also this question contain a hidden one...GADTs!)

You can use an abstract base class, and then inherit one class for each constructor (e.g. base class Expression, and concrete subclasses Mul, Add, etc.). Then you can use runtime type reflection to figure out which kind of Expression you have and branch on it.



--
Sebastian Sylvan
+44(0)7857-300802
UIN: 44640862
_______________________________________________
Haskell-Cafe mailing list
Haskell-Cafe <at> haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe
Kaveh Shahbazian | 18 May 15:59

Re: Mapping Haskell Concepts To C# 3

Hi

(I did not received your message in my mail box and I have seen it on mailing list. I dot know why this happened (?).)

/*
    Maybe I am misguessing why you are asking your question, but wouldn't it be better to ask how to map these Haskell concepts to CLR? If so, check out work on Mondrian.
*/

My intention is to employ Haskell techniques in C# where it fits. If I were going to implement Haskell on CLR the way you mentioned was proper.

For something like: type Thing a b = ThisWay a | ThatWay b | NoWay actually there is no equivalents for data constructor 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!

Thank you

_______________________________________________
Haskell-Cafe mailing list
Haskell-Cafe <at> haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe

Re: Mapping Haskell Concepts To C# 3


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


_______________________________________________
Haskell-Cafe mailing list
Haskell-Cafe <at> haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe
Derek Elkins | 17 May 22:27

Re: Mapping Haskell Concepts To C# 3

On Sat, 2008-05-17 at 20:51 +0100, Sebastian Sylvan wrote:
> 
> 
> 2008/5/17 Kaveh Shahbazian <kaveh.shahbazian <at> gmail.com>:
>         I have question on mapping some Haskell concepts to C# 3 ones.
>         Maybe there are not any strict equivalents; yet it helps:
>         
>         1 - What is the equivalent of "Type Constructor" in C#?
> 
> Class declaration. Generic ones. E.g. List<int>, is a type where the
> type constructor List has been applied to the type int.
>  
>         
>         2 - What is the equivalent of "Data Constructor" in C#?
> 
> Constructors, I guess.
>  
>         
>         3 - What is the logical implementation of pattern matching in
>         C#? (For example using structures with indicator fields or
>         using interfaces and inheritance and dynamically dispatch in
>         calling overloaded methods. Also this question contain a
>         hidden one...GADTs!)
> 
> You can use an abstract base class, and then inherit one class for
> each constructor (e.g. base class Expression, and concrete subclasses
> Mul, Add, etc.). Then you can use runtime type reflection to figure
> out which kind of Expression you have and branch on it.

Ideally you would use dynamic dispatch, not "type reflection" for this,
e.g.
abstract class List<A> {
    public abstract int Length();
    public abstract List<A> Append(List<A> xs);
    public abstract B Foldr<B>(Func<A,B,B> cons, B nil);
}

class Nil<A> : List<A> {
    public Nil() {}
    public override int Length() { return 0; }
    public override List<A> Append(List<A> xs) { return xs; }
    public override B Foldr<B>(Func<A,B,B> cons, B nil) { return nil; }
}

class Cons<A> : List<A> {
    public Cons(A a, List<A> as) {
        Head = a; Tail = as;
    }
    public override int Length() { return 1 + Tail.Length(); }
    public override List<A> Append(List<A> xs) {
        return new Cons<A>(Head, Tail.Append(xs));
    }
    public override B Foldr<B>(Func<A,B,B> cons, B nil) {
        return cons(Head,Tail.Foldr(cons,nil));
    }

    public readonly A Head;
    public readonly List<A> Tail;
}

The Foldr method does make some constructors a bit special, but not too
much.

class Append<A> : List<A> {
    public Append(List <A> xs, List<A> ys) {
        Front = xs; Back = ys;
    }
    public override int Length() {
        return Front.Length() + Back.Length();
    }
    public override List<A> Append(List<A> ys) {
        return new Append<A>(this, ys);
    }
    public override B Foldr<B>(Func<A,B,B> cons, B nil) {
        Front.Foldr(cons, Back.Foldr(cons, nil));
    }

    public readonly List<A> Front, Back;
}

We could, of course, define Cons.Append to use the Append class instead.
Luke Palmer | 18 May 17:33

Re: Mapping Haskell Concepts To C# 3

2008/5/17 Kaveh Shahbazian <kaveh.shahbazian <at> gmail.com>:
> 3 - What is the logical implementation of pattern matching in C#? (For
> example using structures with indicator fields or using interfaces and
> inheritance and dynamically dispatch in calling overloaded methods. Also
> this question contain a hidden one...GADTs!)

C# is missing ADT's, so the most straightforward way to do it is using
open derived classes.  (Forgive if my syntax is a bit wrong, you get
the idea)

   class Thing<a,b> { }
   class ThisWay<a,b> : Thing<a,b> { public a value; }
   class ThatWay<a,b> : Thing<a,b> { public b value; }
   class NoWay<a,b> : Thing<a,b> { }

Annoyances include having to parameterize the, ahem, "constructors" on
all type parameters, and the openness of the cases.  That is, there is
nothing stopping someone from adding "class TwoWay" later and making
your pattern-matches partial.  Scala is very much like C#, but gets
this point right, FWIW.

A more subtle trick is to use the fold of the ADT as its representation.

   delegate c Thing<a,b>(Func<a,c> thisWay, Func<b,c> thatWay, c noWay)

Then your constructors look like this (if I remember C#'s lambda
syntax correctly):

   ThisWay<a,b> thisWay<a,b>(a value) {
       return new ThisWay<a,b>((thisC, thatC, noC) => thisC(value));
   }
   ...

And a pattern match looks like this:

   String desc = thing(
       x => "ThisWay " + x.toString(),
       x => "ThatWay " + x.toString(),
       () => "NoWay");

Which isn't all that bad, actually.  An advantage is that this
approach does in fact keep the data type closed: you can be sure that
the thing() pattern match does in fact cover all cases of the data
type.   A disadvantage is that there is rather a lot of plumbing (not
really in comparison to the open derived approach though, I suppose).

After those C# guys went to all the trouble to add lambdas and
half-assed type-inference (not that "full-assed" was possible in their
type system, but there are more complete strategies than the one they
took), they could have at least added some half-assed (read: non-G)
ADTs for us too :-).

Luke
Jon Harrop | 18 May 17:33

Re: Mapping Haskell Concepts To C# 3

On Sunday 18 May 2008 16:33:56 Luke Palmer wrote:
> Scala is very much like C#, but gets this point right, FWIW.

Only for certain types, IIRC. Scala was broken with respect to bools the last 
time I looked.

--

-- 
Dr Jon D Harrop, Flying Frog Consultancy Ltd.
http://www.ffconsultancy.com/products/?e

Gmane