
Hello! Could someone explain to me the difference between the following? data Atype = Numeric Integer | A | B C and data Atype = Integer | A | B C Thanks in advance!

On Mon, Sep 21, 2015 at 2:23 PM, goforgit .
Could someone explain to me the difference between the following?
data Atype = Numeric Integer | A | B C
and
data Atype = Integer | A | B C
The second one is an enumeration with three values: "Integer" (which is *not* an integer, nor does it contain one), "A", and "B" which as written there takes a value of some unspecified type C as a parameter. The first one is a enumeration with three values: "Numeric" which takes an Integer as a parameter, "A", and "B" which takes a value of some unspecified type C as a parameter. Note that the "Integer" in the second one has *nothing whatsoever* to do with the *type* Integer. Remember that you must always provide a data constructor with "data"; you cannot simply say "data MyInt = Integer" to "wrap" an Integer, because you have not said what to wrap it *in*. (You may have intended to create a type alias, though; that would be "type", not "data".) A "data" always requires a data constructor name, so the compiler can tell when you are talking about a value of that type by looking for the constructor. -- brandon s allbery kf8nh sine nomine associates allbery.b@gmail.com ballbery@sinenomine.net unix, openafs, kerberos, infrastructure, xmonad http://sinenomine.net

Thanks Brandon, that cleared things up!
On Mon, Sep 21, 2015 at 8:39 PM, Brandon Allbery
On Mon, Sep 21, 2015 at 2:23 PM, goforgit .
wrote: Could someone explain to me the difference between the following?
data Atype = Numeric Integer | A | B C
and
data Atype = Integer | A | B C
The second one is an enumeration with three values: "Integer" (which is *not* an integer, nor does it contain one), "A", and "B" which as written there takes a value of some unspecified type C as a parameter. The first one is a enumeration with three values: "Numeric" which takes an Integer as a parameter, "A", and "B" which takes a value of some unspecified type C as a parameter.
Note that the "Integer" in the second one has *nothing whatsoever* to do with the *type* Integer.
Remember that you must always provide a data constructor with "data"; you cannot simply say "data MyInt = Integer" to "wrap" an Integer, because you have not said what to wrap it *in*. (You may have intended to create a type alias, though; that would be "type", not "data".) A "data" always requires a data constructor name, so the compiler can tell when you are talking about a value of that type by looking for the constructor.
-- brandon s allbery kf8nh sine nomine associates allbery.b@gmail.com ballbery@sinenomine.net unix, openafs, kerberos, infrastructure, xmonad http://sinenomine.net
_______________________________________________ Beginners mailing list Beginners@haskell.org http://mail.haskell.org/cgi-bin/mailman/listinfo/beginners

I have a follow up question, I hope it's alright.
What about the following?
data List a = Empty | Add a (List a)
What does the a mean and why is it possible to put it there?
On Tue, Sep 22, 2015 at 4:54 PM, goforgit .
Thanks Brandon, that cleared things up!
On Mon, Sep 21, 2015 at 8:39 PM, Brandon Allbery
wrote: On Mon, Sep 21, 2015 at 2:23 PM, goforgit .
wrote: Could someone explain to me the difference between the following?
data Atype = Numeric Integer | A | B C
and
data Atype = Integer | A | B C
The second one is an enumeration with three values: "Integer" (which is *not* an integer, nor does it contain one), "A", and "B" which as written there takes a value of some unspecified type C as a parameter. The first one is a enumeration with three values: "Numeric" which takes an Integer as a parameter, "A", and "B" which takes a value of some unspecified type C as a parameter.
Note that the "Integer" in the second one has *nothing whatsoever* to do with the *type* Integer.
Remember that you must always provide a data constructor with "data"; you cannot simply say "data MyInt = Integer" to "wrap" an Integer, because you have not said what to wrap it *in*. (You may have intended to create a type alias, though; that would be "type", not "data".) A "data" always requires a data constructor name, so the compiler can tell when you are talking about a value of that type by looking for the constructor.
-- brandon s allbery kf8nh sine nomine associates allbery.b@gmail.com ballbery@sinenomine.net unix, openafs, kerberos, infrastructure, xmonad http://sinenomine.net
_______________________________________________ Beginners mailing list Beginners@haskell.org http://mail.haskell.org/cgi-bin/mailman/listinfo/beginners

Hello, This means that the List type is parametrized by another type. Think of it as a sort of a function between types. Best regards, Marcin Mrotek

What you wrote is equivalent to the following pseudo-haskell.
*List* takes a type and returns a new type, which represents a list of
elements of that type in this case. Thus *List* is a *type-constructor*.
It has two data-constructors, i.e. there are two ways to create elements of
the type *List a*, for any type a.
-- 'Empty' is a value of type 'List a', for all types 'a'. This is one
possible way to construct elements of type 'List a'.
Empty :: List a
-- 'Add' is a function that takes an element of type 'a', and a 'List a',
and constructs a 'List a' out of them.
Add :: a -> List a -> List a
Using the GHC extension, *GADTs*, it is possible to write code that
directly reflects this structure. Although that is considered an advanced
feature of the language.
{-# LANGUAGE GADTs #-}
data List a where
Empty :: List a
Add :: a -> List a -> List a
On 23 September 2015 at 13:21, goforgit .
I have a follow up question, I hope it's alright.
What about the following?
data List a = Empty | Add a (List a)
What does the a mean and why is it possible to put it there?
On Tue, Sep 22, 2015 at 4:54 PM, goforgit .
wrote: Thanks Brandon, that cleared things up!
On Mon, Sep 21, 2015 at 8:39 PM, Brandon Allbery
wrote: On Mon, Sep 21, 2015 at 2:23 PM, goforgit .
wrote: Could someone explain to me the difference between the following?
data Atype = Numeric Integer | A | B C
and
data Atype = Integer | A | B C
The second one is an enumeration with three values: "Integer" (which is *not* an integer, nor does it contain one), "A", and "B" which as written there takes a value of some unspecified type C as a parameter. The first one is a enumeration with three values: "Numeric" which takes an Integer as a parameter, "A", and "B" which takes a value of some unspecified type C as a parameter.
Note that the "Integer" in the second one has *nothing whatsoever* to do with the *type* Integer.
Remember that you must always provide a data constructor with "data"; you cannot simply say "data MyInt = Integer" to "wrap" an Integer, because you have not said what to wrap it *in*. (You may have intended to create a type alias, though; that would be "type", not "data".) A "data" always requires a data constructor name, so the compiler can tell when you are talking about a value of that type by looking for the constructor.
-- brandon s allbery kf8nh sine nomine associates allbery.b@gmail.com ballbery@sinenomine.net unix, openafs, kerberos, infrastructure, xmonad http://sinenomine.net
_______________________________________________ Beginners mailing list Beginners@haskell.org http://mail.haskell.org/cgi-bin/mailman/listinfo/beginners
_______________________________________________ Beginners mailing list Beginners@haskell.org http://mail.haskell.org/cgi-bin/mailman/listinfo/beginners
-- Regards Sumit Sahrawat

On Wed, Sep 23, 2015 at 2:51 PM, goforgit .
What about the following?
data List a = Empty | Add a (List a)
What does the a mean and why is it possible to put it there?
In addition to the good answers already given, it helps to think of it this way: Here's a list of Bools: data ListBool = EmptyListBool | AddListBool Bool ListBool Here's a list of Chars: data ListChar = EmptyListChar | AddListChar Char ListChar Here's a list of Ints: data ListInt = EmptyListInt | AddListInt Int ListInt Well just look at all that repetition! Surely there must be a way to keep DRY and abstract over all that? Let's see: what's common to all of the above? What stays the same? What changes? Here's something that tries to express and separate out what's "fixed" and what's "insert type here": data ListX = Empty | Add X ListX We're close. That almost but doesn't quite work, because Haskell treats capital X as a concrete type, like Bool and Char and Int. What we want is a type _variable_. And Haskell gives us that, if we use lower-case letters: data List x = Empty | Add x (List x) The parens is needed to distinguish against data List x = Empty | Add x List x which doesn't work for reasons you can probably guess. Finally, it's convention to use type variables a b c and not x y z. -- Kim-Ee

Thank you guys, very good descriptions given on my question. Together with
your answers and the analogy of it being somewhat similar to something in
C++ made me understand how it works. Again many thanks!
On Wed, Sep 23, 2015 at 10:48 AM, Kim-Ee Yeoh
On Wed, Sep 23, 2015 at 2:51 PM, goforgit .
wrote: What about the following?
data List a = Empty | Add a (List a)
What does the a mean and why is it possible to put it there?
In addition to the good answers already given, it helps to think of it this way:
Here's a list of Bools:
data ListBool = EmptyListBool | AddListBool Bool ListBool
Here's a list of Chars:
data ListChar = EmptyListChar | AddListChar Char ListChar
Here's a list of Ints:
data ListInt = EmptyListInt | AddListInt Int ListInt
Well just look at all that repetition!
Surely there must be a way to keep DRY and abstract over all that?
Let's see: what's common to all of the above? What stays the same? What changes?
Here's something that tries to express and separate out what's "fixed" and what's "insert type here":
data ListX = Empty | Add X ListX
We're close.
That almost but doesn't quite work, because Haskell treats capital X as a concrete type, like Bool and Char and Int.
What we want is a type _variable_. And Haskell gives us that, if we use lower-case letters:
data List x = Empty | Add x (List x)
The parens is needed to distinguish against
data List x = Empty | Add x List x
which doesn't work for reasons you can probably guess.
Finally, it's convention to use type variables a b c and not x y z.
-- Kim-Ee
_______________________________________________ Beginners mailing list Beginners@haskell.org http://mail.haskell.org/cgi-bin/mailman/listinfo/beginners

Again, I have a follow up question related to that list.
Is it possible to make the list an instance of something in order to use
for example takeWhile on List?
Thanks in advance!
On Wed, Sep 23, 2015 at 9:51 AM, goforgit .
I have a follow up question, I hope it's alright.
What about the following?
data List a = Empty | Add a (List a)
What does the a mean and why is it possible to put it there?
On Tue, Sep 22, 2015 at 4:54 PM, goforgit .
wrote: Thanks Brandon, that cleared things up!
On Mon, Sep 21, 2015 at 8:39 PM, Brandon Allbery
wrote: On Mon, Sep 21, 2015 at 2:23 PM, goforgit .
wrote: Could someone explain to me the difference between the following?
data Atype = Numeric Integer | A | B C
and
data Atype = Integer | A | B C
The second one is an enumeration with three values: "Integer" (which is *not* an integer, nor does it contain one), "A", and "B" which as written there takes a value of some unspecified type C as a parameter. The first one is a enumeration with three values: "Numeric" which takes an Integer as a parameter, "A", and "B" which takes a value of some unspecified type C as a parameter.
Note that the "Integer" in the second one has *nothing whatsoever* to do with the *type* Integer.
Remember that you must always provide a data constructor with "data"; you cannot simply say "data MyInt = Integer" to "wrap" an Integer, because you have not said what to wrap it *in*. (You may have intended to create a type alias, though; that would be "type", not "data".) A "data" always requires a data constructor name, so the compiler can tell when you are talking about a value of that type by looking for the constructor.
-- brandon s allbery kf8nh sine nomine associates allbery.b@gmail.com ballbery@sinenomine.net unix, openafs, kerberos, infrastructure, xmonad http://sinenomine.net
_______________________________________________ Beginners mailing list Beginners@haskell.org http://mail.haskell.org/cgi-bin/mailman/listinfo/beginners

On Fri, Sep 25, 2015 at 2:10 PM, goforgit .
Is it possible to make the list an instance of something in order to use for example takeWhile on List?
Not presently for takeWhile; it's specific to the built-in list type. Things are gradually being migrated to Foldable and Traversable, though. -- brandon s allbery kf8nh sine nomine associates allbery.b@gmail.com ballbery@sinenomine.net unix, openafs, kerberos, infrastructure, xmonad http://sinenomine.net

Alrighty then, thanks brandon!
On Fri, Sep 25, 2015 at 8:20 PM, Brandon Allbery
On Fri, Sep 25, 2015 at 2:10 PM, goforgit .
wrote: Is it possible to make the list an instance of something in order to use for example takeWhile on List?
Not presently for takeWhile; it's specific to the built-in list type. Things are gradually being migrated to Foldable and Traversable, though.
-- brandon s allbery kf8nh sine nomine associates allbery.b@gmail.com ballbery@sinenomine.net unix, openafs, kerberos, infrastructure, xmonad http://sinenomine.net
_______________________________________________ Beginners mailing list Beginners@haskell.org http://mail.haskell.org/cgi-bin/mailman/listinfo/beginners
participants (5)
-
Brandon Allbery
-
goforgit .
-
Kim-Ee Yeoh
-
Marcin Mrotek
-
Sumit Sahrawat, Maths & Computing, IIT (BHU)