Talk:Haskell/Type basics

DavidHouse and Kowey Chat transcript
I had a chat with Kowey about where this was going. Here are my notes from the discussion. DavidHouse 19:46, 24 July 2006 (UTC)

On 24th July 2006, I chatted with kowey about my new 'Type basics' module. He had some comments, which I enumerate here, along with proposed actions. The original conversation is included for reference.

Kowey liked it :)
 * Step-by-step guide for building the type of a function

Probably not so great, because: - They're not too useful right away - They involve a bit too much low-level explanation (ASCII etc.)
 * chr and ord used as examples
 * TODO: Use unlines/unwords instead.

They need to be integrated before the Type chapter.
 * Tuples
 * TODO: Place them in the Lists chapter (and do a rename).

- Could be confusing from a mathematical perspective. - Would be nice to compare the two approaches somewhere, pointing out that currying gives you partial application. - A footnote in the 'Higher-order functions and Currying' module would be good.
 * Currying versus tuples for functions in more than one argument
 * TODO : add said footnote.

We seem to have a focus on subtyping. This is probably not entirely intended and not the idea. We want to get four things across: 1. Everything in Haskell has a type. 2. Everything in Haskell has only one type, apart from polymorphic things. - Should we give up on this completely? - It's important to note that, for example, nothing can have both type Int and String. 3. Types help you categorise things. 4. Types help you avoid errors.
 * The greengrocer metaphor

The introduction is a bit long. Basically, we want to give the user enough feet to stand on, then plunge them into something more practical. Be wary that starting with exercises before the theory is sufficiently developed is scary and confusing and definitely something to avoid. However, it's probably better to teach them *how* something is before we teach them *why* it is. Once they have a grasp on the structure they can grasp the motivation.
 * Teaching style

Or perhaps a slightly different architecture, which looks like this? 1. _Brief_ motivation. 2. Explanation of *what* types are. 3. More full explanation of *how* types are useful.

This seems to be a fairly common approach in textbooks, etc.

17:41 -!- Irssi: Starting query in freenode with kowey 17:41 still there? 17:41 Yup. 17:42 i have some comments on type basics, if you want them now 17:42 Sure. 17:42 first of all, i really liked the fact that you gave practical step-by-step on how to write the type of a function 17:43 that's the kind of stuff that helps the 1st year undergrad type crowd a lot (not that this is neccesarily our target audience) 17:43 let's see... 17:43 note number 2 17:44 i wouldn't use chr and ord for examples, because (1) they aren't going to be immediately useful (2) they introduce a lot of underlying how-computers-work stuff 17:45 now (2) might be a strong point if you take a holistic view of things, but i'm somewhat afraid of confusing the reader 17:45 True. 17:45 perhaps stuff like unlines and unwords would work 17:45 There aren't many monomorphic functions in a single argument floating around, though :) 17:45 since we've already introduced lists 17:46 yeah, i was thinking that might have been why you chose them, so i glanced through the Prelude to find suggestions 17:46 That's true. 17:46 note number 3 17:46 we ought to remember to actually introduce tuples some point before this 17:46 before or after lists, i'm not too sure 17:46 note number 4 17:47 Yeah. 17:47 Perhaps add them to the Lists chapter. Lists -> Lists and Tuples 17:47 i recall when teaching that some of my students got confused between functions that take tuples as arguments 17:47 (YAHT introduces them together) 17:47 Right, if you're into mathematics then that's likely to be confusing. 17:47 (we probably should do that, introduce them together, it's easy to get them confused) 17:48 well, it's funny, it's one of my slow students that did that :-) 17:48 Hehe, okay. 17:48 like you know, when somebody who just doesn't grasp it stumbles on to something immensely profound 17:48 and of course, it'd just confuse the living daylights out of him to tell him he's almost right... 17:49 Currying and tuples are two ways of doing the functions-in-more-than-one-argument stuff, maths and LC just go their different ways. 17:49 but yeah, i'm not sure if it'll be something we want to head off, or if doing so will just confuse users even more 17:49 i guess we'll get to them during the currying chapter 17:49 Yeah. 17:49 note number 5 17:50 there's a danger in the greengrocer metaphor... 17:50 Perhaps we could do an appendix? We could go into some detail. "This is how maths does it. It'd work, but you don't get partial application.". Or perhaps a footnote in currying saying "Look how cool partial application is! That's why we don't use tuples." 17:51 well, there's many places to talk about this 17:51 e.g. 17:51 1) just after introducing tuples (as a footnote) 17:51 2) a footnote in the types stuff 17:52 3) a chapter on partial application and the cool stuff like returning a function (higher order functions) 17:52 I like 3. 17:52 ok, i think i could be happy with that 17:52 Note number 5? 17:52 right, the greengrocer metaphor 17:53 you seem to be getting into some notion of a type hierarchy, like first fruit and vegetables, and then shapes under that 17:53 is that on purpose? 17:53 Somewhat. 17:53 I'm keen to introduce the fact that types give you information. 17:54 But perhaps explicit subtyping is the wrong way of doing it, as Haskell doesn't have it :) 17:54 well, what i'd tend to feel is that yeah, 17:54 our highest priority is to introduce the notion that everything in haskell has a type 17:54 and only one type 17:54 (uh... though it could be a polymorphic type, but we do cover that) 17:54 True. That might be a confusing point. 17:55 yeah, that was gnawing at me during my conference :-) 17:55 i guess this blends in with note number 6 17:55 Hehe. Did you not have internet access? 17:55 i did, but not much time to be looking at it... i was on a mail and wikibooks watchlist diet 17:56 have lost much time since doing internet bulimia 17:57 anyway, note number 6 is likely just a matter of taste... my outlook on pedagogical stuff -- and i caution you that i'm a pretty horrible teacher, so my pedagogical views should be taken with a good shakerful of salt - 17:57 uh... my outlook tends to be "first manipulate, THEN motivate" 17:58 that is, i tend to like a hands-on approach... first the student should be able to do something with the stuff, try examples out himself, do exercises, etc 17:58 and only when s/he has some concrete grasp of it should we try to delve into why this is useful 17:59 Agreed. 17:59 so, sort of the chop-wood-and-carry-water school of thought 17:59 in other words, i think the introduction is a bit long, and i'd rather we hit the ground running 17:59 Okay. 17:59 i guess the 3 things we want to convey are 17:59 1) everything in Haskell has a type 18:00 We still need some notion of what types *are*. 18:00 2) everything has onely one type 18:00 3) types let you categorise stuff 18:00 4) types let you avoid errors 18:00 I've been in situations before where the tutorials haven't given enough before they started with the examples and exercises, and you're left thinking "What am I meant to be doing?" 18:00 that is the other excess 18:01 in fact, i have a friend who dislikes yaht precisely for this reason (IO) 18:01 i tried to apologise for YAHT by saying that Hal didn't really have much of a choice, because explaining monads before IO... eh... good luck 18:01 so i guess the order i'd have in mind is something like 18:02 what - how - why 18:02 (how being the examples and exercises stuff) 18:02 and that being said 18:02 although i do agree that examples are the best way to learn (learn by doing, etc) 18:03 Yeah. 18:03 it really do irks me when people insist on teaching-by-example (as opposed to actually teaching) 18:04 students who tend to insist you don't give them any text but for examples also annoy me 18:05 If you want to hack around, please do. 18:06 thanks... i confess that i'll have to commit the easier-said-than-done sins, i.e. complaining about other people's stuff without actually taking the effort to do better 18:06 Not at all. 18:06 Getting peer-review was harder than I anticipated. 18:06 i'm probably not going to be hacking around, (have to get back to real life/work sometime), but i hope the comments are useful by themselves 18:07 Yep. 18:07 I'll see what I can come up with. 18:07 people on #haskell and the lists aren't saying much, are they? 18:07 on the book, that is 18:07 I convinced shapr to have a look around. 18:08 I think once a few more modules are done we should do an ANNC on the lists. 18:08 yeah, i was pleased with that... having you in the project is very nice because i personally am too shy to plug the book 18:08 but you've been doing a good job keeping it somewhere in the awareness-meter of #haskell 18:09 the yaht import might be our turning point... i'm going to do the same thing as in the scheme 48 one... make yaht a subtutorial under Haskell 18:09 and then hope we cannibalise from it 18:09 Awesome. 18:10 *assuming* hal actually responds to my mail... but the fact that we had face to face contact increases the probability that he does 18:10 * kowey hopes intensely 18:10 right... anyway, i ought to get back to work... catch you later! 18:11 Thanks!
 * Original conversation log

Comments on comments
One thought I had forgotten to mention. and  look like they would be useful for making a little ciphering exercise, like a rot13 thingy or something more amusing. -- Kowey 20:12, 24 July 2006 (UTC)

There's a section that says numeric types are "deferred until later". Where is this??!? Link please.

Functions in more than one argument
"Functions in more than one argument" were already introduced in a previous chapter: http://en.wikibooks.org/wiki/Haskell/Variables_and_functions#Multiple_parameters

I'd just remove it from here.

Subtyping

 * I'm moving the subtyping stuff here. I think it could be useful in the advanced chapters maybe, or maybe re-written to be more Haskell-newbie oriented -- Kowey 13:37, 28 November 2006 (UTC)

Categorising bits of data
Let's imagine we're a greengrocer. We had our daily delivery of fresh, juicy and healthy fruit and vegetables this morning, but unfortunately, the delivery van went round a corner a little too fast and all our produce is mixed up! Of course, we're only greengrocers by day. We love to program and as such our methods as a greengrocer are meticulous and organised.

Presented with this mess, we're going to sort out our food by category. First, we split the foodstuffs into two piles, fruit and vegetables. Next, let's go a bit further and subcategorise each pile by shape (why not?). The melons go next to the grapefruit, but they're a long way away from the bananas. And although the lettuce and the pomegranate are a similar shape, they're not placed next to each other, because the former is a vegetable and the latter a fruit: they're already been split up. We could go further along this process, splitting things up by colour, taste, price, etc, but we're suddenly interrupted by a pressing business engagement and so have to leave it there.

What's this got to do with types? The important thing to realise about types is that they're one level removed from values. In the same way that every piece of fruit on our floor belongs to one of these groups, so does every value in Haskell belong to a certain type. Types are 'groups of values'; a label which describes certain properties of the value. In our greengrocer analogy, if we knew a certain piece of food lay in the 'Fruit' category, then we know that it's a ripened ovary -- together with seeds -- of a flowering plant. Knowing a value has some type, say, Number, will tell you certain things about that value (in the case of some data having type Number, we know, for example, it can be represented by a sequence of digits and added and subtracted to and from other numbers).

Ugly
I am finding this module, at least the beginning to be cluttered and generally bad layout. Does anyone agree here?

Jptdrake 06:01, 20 March 2007 (UTC)

isL
The "l" in "isL" looks a lot like the number 1. Perhaps a different letter would be a better choice? There was also an "l" variable in one of the previous chapters that was hard to read. 65.201.194.91 18:31, 22 June 2007 (UTC)

Example: not
remember, people reading this are newbies. I saw

not True = False not False = True

and wondered if that was something I was supposed to type in:

Prelude> not True = False :1:9: parse error on input `='

Then I thought, "oh, that's the way 'not' is defined in a file", and did that in a file, tried to run it and got

*Main> not True

It could refer to either `not', defined at test.hs:1:0 or `not', imported from Prelude

If you've been doing haskell for a long time, I expect when you see this you're just thinking "he's showing how 'not' is defined in the Prelude" or whatever--I think it should say "here is now 'not' is defined in the Prelude" before it puts those lines there, to help us newbies along. -- Msouth 13:21, 15 July 2007 (UTC)

Note 1 is unclear
Note 1 says "in fact, these are one and the same concept in Haskell"--meaning what are one and the same? values and functions? typing values and typing functions?

I suspect (but I'm a newbie, so I don't know, otherwise I would just change the note) that it means "function is merely a particular variety of value, so just like a value has a type, a function has a type".

-- Msouth 13:28, 15 July 2007 (UTC)

Functions in more than one argument
Is there anything that can be done about the fact that if you actually define f as shown, then try looking at the type with :t you get:

*Main> :t testf testf :: (Num a) => a -> a -> a

I see the a -> a -> a part that corresponds to your Int -> Int -> Int, but I don't know what the (Num a) => is about, and I don't know how to define a function that really requires ints so I can't tell if it's because this function accepts all Num things that it has that at the beginning or do all functions? And what is => for?

-- Msouth 13:53, 15 July 2007 (UTC)

Agreed; this is terrible.

207.172.223.249 (discuss) 17:38, 31 December 2011 (UTC)

consider dropping the ord and chr part now
I don't see what they add now that the other example is there. The other example turned out to need digression to explain the \n's. The ord/chr things needs to digress to explain ASCII. It ends up being way too much digression, leaving me wondering what new thing I learned (other than how to load a module). I think it would work fine with ord/chr stuff just deleted. Msouth 13:56, 15 July 2007 (UTC)

module for openWindow?
It talks about openWindow function, but doesn't tell me what module I need to load to look at the type myself with :t. Msouth 14:01, 15 July 2007 (UTC)

Loading Data.Char in WinHugs
:l Data.Char works, however -- I got this fix from http://www.cs.nott.ac.uk/~gmh/errata.html

confusing wording
"So far, what we've done just seems like categorizing things -- hardly a feature which would cause every modern programming language designer to incorporate into their language!" That last clause is a bit incorrect in a way that makes the meaning unclear. It's probably not important, though.
 * Destynova (talk) 20:33, 10 February 2008 (UTC)

Module without type signatures
I found these two example in section of "Type signatures in code" has a lot of things that does not metioned in previous chapter, for example, the map and (x:xs).

This make me feel distraction to think about what heck the code is, and the most important thing, the syntax of how to declare function type, has became unobvious.

Could we just use something we worte in chapter "Next step" and add type signatures to them as a example?

For example: mySignum x :: Int -> Int mySignum x = if x < 0 then -1 else if x > 0 then 1 else 0

I think it is much more clear then current examples.


 * BrianHsu 07:27, 24 Sep 2008 (UTC)

Type signatures in code example uses point-free style
You said you didn't want to introduce something new without explaining, but here's a glaring example of just such an inclusion. These should be rewritten in a style new readers are already accustomed to. It's mentioned for the first time in http://en.wikibooks.org/wiki/Haskell/List_processing.

Very good. It would be helpful to know which type signature checks require a module import before describing them. 91.135.3.166 (talk) 16:16, 31 August 2010 (UTC)

I agree that this section has some problems. It introduces code in modules (not yet discussed) that uses partial application (not yet discussed) with the map function (not yet discussed) for list processing using the cons operator (both of which are not yet discussed)... Hopefully it is obvious now that it violates the principle of not using anything that has not yet been taught (or even mentioned, sometimes) to the reader. Digichoron (discuss • contribs) 16:15, 4 April 2011 (UTC)


 * The unexplained features are intentional: the point is that type signatures can provide useful information even if you don't understand the implementation. I agree that such a strategy can be distracting, and that the text doesn't make its intent as clear as it could be. I will try to think of a way to improve this section... --Duplode (discuss • contribs) 01:34, 2 April 2012 (UTC)

Is it really that type signatures are needed ONLY for documentation and debugging or are there situations where the compiler cannot infer a type?
In the section that talks about type inference, below the phrase "So if type signatures are optional why bother with them at all? Here are a few reasons: ..." only 2 reasons are stated. One is saying that it helps documenting the code and the other one for debugging. I am myself newly learning Haskell and I am wondering if these are the ONLY 2 reasons for having type signatures or if there are situations where the compiler cannot infer the types. If it is true that there are only these 2 reasons, then maybe it should be made clear that there are no other reasons, otherwise it might be better to hint that there are some rare situations where the compiler cannot infer (and maybe link to the section where it is described).


 * Good point. There are situations in which type inference is not enough to make all signatures optional, but I think it would be difficult to talk about such situations at this point. In any case, the text needs to be made clearer. --Duplode (discuss • contribs) 01:39, 2 April 2012 (UTC)

Types overview and signatures?
Since in the ongoing chapters the Types are used, I would find it quite helpful to have a summary of

- what types are in Haskell available? - how do the transform into each other?

e.g. in https://en.wikibooks.org/wiki/Haskell/Type_basics_II you explain quite well fromIntegral, use the type Integral and explain that Fractional is a subtype of Num. So, I would be happy to have an overview what types are available and for which types I need a tranformation and for which none.

Additionally I would prefer as well a more clear hint reg. How to read the type-signatures? namely that the very right is the type of the return argument. But how to read the rest, e.g. what's the meaning of ? Or perhaps there are better (?) samples to illustrate how the signatures should work.

AND an explanation about  would be also beneficial, or even better that   is an explicit conversion and again: What is the meaning of the :: ?

At least these three items I would find beneficial for a beginner.


 * "what types are in Haskell available"? Lots of them? :) The richness of the type system, combined with the effective lack of a boundary between primitive types and user/library defined ones means there would be a lot of ground to cover. We might attack some parts of it with cheat sheets for subsets of the type system (e.g. number types). Somewhat related is something that the book is in dire need of: a concise overview of key data structures (key-value maps, popular array implementations,,   and so forth).
 * can be read as "A function which takes two arguments of some type  and produces a value of type , with   being an instance of (the class)  ". Or, adopting the view that all Haskell functions have just one argument, "A function which takes an argument of some type   and produces a value of type  , with   being an instance of  ". I will try to sneak a brief note to that effect into the text, either in Type Basics II or in Haskell/Classes and types.
 * is, to use the nomenclature of the Report, an expression type-signature - an inline signature, in this case with scope limited by the parentheses. It occasionally is needed to resolve types when neither the regular signatures you wrote nor the type inference are enough. One traditional example is, which will only work in e.g. GHCi if you use an expression signature, as in   or  . I agree it would be good to mention it in the book; I'm just not sure about where.
 * It should be mentioned that I find this first Type Basics chapter a little messy. I intend at some point to reorganize and streamline it a bit.
 * Duplode (discuss • contribs) 04:09, 13 April 2014 (UTC)