Hello to everybody I am an new user of Haskel and generally in functional programming and I could say that I am very impressed from this Language. Though I can't understand the use of datatypes. Let's take a firly simple situtation e.g. data Pair a b = Pair a b i.e. an new type with name Pair parameterized over the types a,b with one Constructor named Paid which take two values of type a,b a more complex one would be data Either a b = Left a | Right b i.e a new type named Either parameterized over the types a, b and two Constructors 1. Left which take one value of type a and 2. Right which takes one value of type b I consider that the definitions above are well formulated. Nevertheless I can't understand them quite well. I have read that datatypes are used to define new structures. So, is there any corresponding example in C, sinch I am quite familiar with structures in it? I hope the word C here is allowed here :o) Thanks
On Feb 9, 2008, at 19:09 , Mattes Simeon wrote:
e.g. data Pair a b = Pair a b
struct Pair { a pair_a; b pair_b; };
data Either a b = Left a | Right b
union Either { enum { Left, Right } _tag; a either_left; b either_right; }; (except that Haskell makes sure you use it properly, while C will let you access foo.either_right when foo._tag == Left). -- brandon s. allbery [solaris,freebsd,perl,pugs,haskell] allbery@kf8nh.com system administrator [openafs,heimdal,too many hats] allbery@ece.cmu.edu electrical and computer engineering, carnegie mellon university KF8NH
On Feb 10, 2008 12:09 AM, Mattes Simeon <simeon.mattes@gmail.com> wrote:
Hello to everybody
I am an new user of Haskel and generally in functional programming and I could say that I am very impressed from this Language. Though I can't understand the use of datatypes.
Let's take a firly simple situtation
e.g. data Pair a b = Pair a b
i.e. an new type with name Pair parameterized over the types a,b with one Constructor named Paid which take two values of type a,b
a more complex one would be data Either a b = Left a | Right b
i.e a new type named Either parameterized over the types a, b and two Constructors 1. Left which take one value of type a and 2. Right which takes one value of type b
I consider that the definitions above are well formulated. Nevertheless I can't understand them quite well.
I have read that datatypes are used to define new structures. So, is there any corresponding example in C, sinch I am quite familiar with structures in it? I hope the word C here is allowed here :o)
I guess C++ would be closer... template< class A, class B> struct Pair { A fst; B snd; } template< class A, class B> struct Either { enum {Left, Right} tag; union{ A left; B right; }; } In the second example the tag would be used to figure out which of the two alternatives the structure actually is. In Haskell you can just pattern match on the constructor. -- Sebastian Sylvan +44(0)7857-300802 UIN: 44640862
Thanks for your help. It was very useful. Though in comparison with C or C++ I can't figure out so clear the syntax. Maybe it has to do with the syntactic Sugar of each Language. I 'll give you a similar example I saw in a book for Haskel The following program just returns the value of the position of a datatype Tuple which can hold one or two elements. data Tuple a b = One a | Two a b tuple1 (One a)= Just a tuple1 (Two a b) = Just a tuple2 (One a) = Nothing tuple2 (Two a b) = Just b The corresponding Version in C++, which seems to be more appropriate, would be template<class A, class B> struct Tuple { enum (One, Two) tag; union { A either_one; struct nOne { A either_two B two; }; }; } Am I wrong. If not, how can I use it in the corresponding function in C++? I seems realy strange, and I'm confused. Surely a solution to this would be to use the standard types of Haskel for tuples and check out each time if I have just a number or a tuple. But this is how somebody thinks in imperative languages. Functional programming is something more, isn't it? Sorry for beeing so naive, but although unions, enum, structure are just some tools in C, surely something more in C++, in Haskell they are seem to be a standard.
On Feb 10, 2008 3:40 PM, Mattes Simeon <simeon.mattes@gmail.com> wrote:
Thanks for your help. It was very useful.
Though in comparison with C or C++ I can't figure out so clear the syntax. Maybe it has to do with the syntactic Sugar of each Language. I 'll give you a similar example I saw in a book for Haskel
The following program just returns the value of the position of a datatype Tuple which can hold one or two elements.
data Tuple a b = One a | Two a b tuple1 (One a)= Just a tuple1 (Two a b) = Just a
tuple2 (One a) = Nothing tuple2 (Two a b) = Just b
The corresponding Version in C++, which seems to be more appropriate, would be
I think this is the most native way to do it in C++: template <class A, class B> class Tuple { public: static Tuple<A, B> *One (A *a) { return new One (a); } static Tuple<A, B> *Two (A *a, B *b) { return new Two (a, b); } virtual A *tuple1 () = 0; virtual B *tuple2 () = 0; }; template <class A, class B> class One : Tuple<A, B> { public: One (A *a) { this->a = a; } A *tuple1 () { return a; } B *tuple2 () { return NULL; } private: A *a; } template <class A, class B> class Two: Tuple<A, B> { public: Two (A *a, B *b) { this->a = a; this->b = b} A *tuple1 () { return a; } B *tuple2 () { return b; } private: A *a; B *b; } -- vir http://vir.comtv.ru/
G'day all. On Feb 10, 2008 3:40 PM, Mattes Simeon <simeon.mattes@gmail.com> wrote:
Though in comparison with C or C++ I can't figure out so clear the syntax.
Quoting Victor Nazarov <asviraspossible@gmail.com>:
I think this is the most native way to do it in C++:
Herb Sutter and Andrei Alexandrescu will find you and beat you up if you write this. This is considered more appropriate. (Warning: untested code follows.) #include <boost/variant.hpp> template<typename A, typename B> class Tuple : public boost::variant<A, std::pair<A,B> > { private: typedef std::pair<A,B> pair_type; typedef boost::variant<A, pair_type> base_type; struct visitor_A : public boost::static_visitor<const A*> { const A* operator()(const A& a) { return &a; } const A* operator()(const pair_type& p) { return &p.first; } }; public: Tuple(const A& a) : base_type(a) { } Tuple(const A& a, const B& b) : base_type(pair_type(a,b)) { } const A* tuple1() const { return boost::apply_visitor(visitor_A(), *this); } const B* tuple2() const { const pair_type* p = boost::get<pair_type>(*this); return p ? &p->second : 0; } }; But in this specific case, this might be more appropriate: template<typename A,typename B> class Tuple { A m_a; boost::optional<B> m_b; // etc }; Cheers, Andrew Bromage
Mattes Simeon <simeon.mattes@gmail.com> wrote:
Though in comparison with C or C++ I can't figure out so clear the syntax...I seems realy strange, and I'm confused.
Surely a solution to this would be to use the standard types of Haskel for tuples and check out each time if I have just a number or a tuple. But this is how somebody thinks in imperative languages. Functional programming is something more...
The data declarations in Haskell are well-suited to pattern matching -- you have a compact way to express each alternative, so you can match on that alternative. The C++ way offers a *uniform* interface to every alternative, so you can do if-tests that will type check. The "do an if test at runtime" way is very general, but basically unoptimizable; whereas pattern matching is very specific, and can be optimized (see page 5 of Luca Cardelli's [Compiling ML]).
Sorry for beeing so naive, but although unions, enum, structure are just some tools in C, surely something more in C++, in Haskell they are seem to be a standard.
It's certainly true that Haskell elevates certain common data structures to the level of 'native citizens', providing short cut syntax and so forth. Personally, I think C's approach is an example of neglect in this domain, not sparseness; however, at the time C was introduced, I would not have said the same thing at all. -- _jsn [Compiling ML]: http://lucacardelli.name/Papers/CompilingML.pdf
On the subject of data types, I've recently seen Haskell code using data Foo ... = Foo { ... } where I would have used newtype instead of data. When is it a good idea to avoid newtype?
ok:
On the subject of data types, I've recently seen Haskell code using data Foo ... = Foo { ... } where I would have used newtype instead of data. When is it a good idea to avoid newtype?
It depends what's in the ... If its just something with the same representation as an existing type, using a newtype makes sense. If it builds a more complicated single-contructor type, such as many record types, then data is required. -- Don
"Richard A. O'Keefe" <ok@cs.otago.ac.nz> writes:
On the subject of data types, I've recently seen Haskell code using data Foo ... = Foo { ... } where I would have used newtype instead of data. When is it a good idea to avoid newtype?
When the code was written before newtype was introduced into the language? Also when { ... } is not a single type. -- Jón Fairbairn Jon.Fairbairn@cl.cam.ac.uk
participants (9)
-
ajb@spamcop.net -
Brandon S. Allbery KF8NH -
Don Stewart -
Jason Dusek -
Jon Fairbairn -
Mattes Simeon -
Richard A. O'Keefe -
Sebastian Sylvan -
Victor Nazarov