Hobby-hacking Eric

Showing posts with label haskell wikibook. Show all posts
Showing posts with label haskell wikibook. Show all posts

2009-06-24

Haskell syntax highlighting on Wikipedia and Wikibooks

If you edit the Haskell Wikibook and Wikipedia entries with Haskell in them, you may be interested to note that Haskell syntax highlighting is now available on all Wikimedia projects.

Example:
<source lang="haskell">
-- foo
let x = foo
</source>


2007-08-14

Haskell 是一门函数式编程语言。

Looks like some wikibookian(s) have embarked upon a Chinese translation of the Haskell wikibook. Good luck to them! Chinese speakers might be interested in jumping on board. As for non Chinese speakers, the sentence above is "Haskell is a functional programming language."


2007-07-19

monomorphism redux

There may be errors in this, of course!

the context from wikibooks


Following the previous example, you might be tempted to try storing a value for that radius. Let's see what happens:
Prelude> let r = 25
Prelude> 2 * pi * r

<interactive>:1:9:
Couldn't match `Double' against `Integer'
Expected type: Double
Inferred type: Integer
In the second argument of `(*)', namely `r'
In the definition of `it': it = (2 * pi) * r


Whoops! You've just run into a programming concept known as types. Types are a feature of many programming languages which are designed to catch some of your programming errors early on so that you find out about them before it's too late. We'll discuss types in more detail later on in the Type basics chapter, but for now it's useful to think in terms of plugs and connectors. For example, many of the plugs on the back of your computer are designed to have different shapes and sizes for a purpose. This is partly so that you don't inadvertently plug the wrong bits of your computer in together and blow something up. Types serve a similar purpose, but in this particular example, well, types aren't so helpful.

the new monomorphism-based explanation


The quick solution to this problem is to specify a type for the number 25. For lack of other information, Haskell has "guessed" that 25 must be an Integer (which cannot be multiplied with a Double). To work around this, we simply insist that it is to be treated as a Double
Prelude> let r = 25 :: Double
Prelude> 2 * pi * r
157.07963267948966


Note

There is actually a little bit more subtlety behind this problem. It involves a language feature known as the monomorphism restriction. You don't actually need to know about this for now, so you can skip over this note if you just want to keep a brisk pace. Instead of specifying the type Double, you also have given it a polymorphic type, like Num a => a, which means "any type a which belongs in the class Num". The corresponding code looks like this and works just as seamlessly as before:
Prelude> let r = 25 :: Num a => a
Prelude> 2 * pi * r
157.07963267948966


Haskell could in theory assign such polymorphic types systematically, instead of defaulting to some potentially incorrect guess, like Integer. But in the real world, this could lead to values being needlessly duplicated or recomputed. To avoid this potential trap, the designers of the Haskell language opted for a more prudent "monomorphism restriction". It means
that values may only have a polymorphic type if it can be inferred from the context, or if you explicitly give it one. Otherwise, the compiler is forced to choose a default monomorphic (i.e. non-polymorphic) type. This feature is somewhat controversial. It can even be disabled with the GHC flag (-fno-monomorphism-restriction), but it comes with some risk for inefficiency. Besides, in most cases, it is just as easy to specify the type explicitly.


2007-07-17

Write Yourself a Scheme in 48 Hours (PDF)

One of the wikibookians has made a rather nice PDF out of Johnathan Tang's Write Yourself a Scheme in 48 Hours. The conversion was done semi-automatically from mediawiki syntax to LaTeX [in Java... tsk]. Many thanks to Hagindaz for the conversion!


2007-07-15

monomorphism and the unintentional fib

The monomorphism restriction is a simple problem with a scary name.

I think I've run into the first instance where I have actually been able to identify something as being the monomorphism restriction in action (*). The good news is that if you don't understand what the restriction is, this might be your chance. The bad news is that many Haskell newbies might have been hurt in the process, because it involves an unintentional fib that I told in near the beginning of the Haskell wikibook.

(*) I'd appreciate it if somebody could fact-check me on this.

circles and half-truths

High school Geometry. We've got a circle of radius 25 and we want to know its circumference (2 * pi * r). Now let's see what happens when we type it into GHCi

Prelude> let r = 25
Prelude> 2 * pi * r

<interactive>:1:4:
No instance for (Floating Integer)
arising from use of `pi' at :1:4-5
Possible fix: add an instance declaration for (Floating Integer)
In the second argument of `(*)', namely `pi'
In the first argument of `(*)', namely `2 * pi'
In the expression: (2 * pi) * r


Oops! At this point, the reader runs into types for the very first time. This morning, I realised to my horror that I might have given a very wrong explanation of the problem to the gentle Haskell newbie. I said

The main problem is that Haskell doesn't let you multiply Integers with real numbers. We'll explain why later, but for now, you can get around the issue by using a Double for r so that the pieces fit together:

Prelude> let r = 25.0
Prelude> 2 * pi * r
157.07963267948966


Which is true, but is only sort of a half-truth. The problem with my explanation is that it lets the reader walk away with the mistaken belief that numbers without a decimal point, such as 25, can only be integers, when really they can be any Num a. It's as if somebody had taught OCaml too recently and forgotten that haskell /= ocaml! (Coughs discretely)

A concrete example of why it's important to get this right can be found further down the chapter. Here, I want to show that we can use variables within other variables. So here's what I have the reader type in area = pi * 5^2:
Prelude> let area = pi * 5^2

And here everything works... except...


Except if you are a sharp-eyed reader, you remember from above that I had just said that types prevent you from multiplying integers with reals and I had unintentionally implied that numbers like 5 are integers. So if you are a sharp-eyed reader, you look at that thing and you say to yourself, "HUH? That shouldn't work! You can't multiply an integer with a real!"

monomorphism, like polymorphism without the poly

The real problem is not that we had set r to an integer. By right r = 25 should give us any Num a => a; however, since we do not give it a type signature, r gets restricted to being an Integer. In fact, the example of 2 * pi * r would have worked if (a) we had given r a polymorphic type signature or (b) we had run GHC with its 'no monomorphism restriction' extension.

polymorphic type signature

Here we add an explicit type signature to r. Everything works:
Prelude> let  r :: Num a => a; r = 25
Prelude> 2 * pi * r
157.07963267948966
(Thanks to shachaf on #haskell for reminding me that we can use {}/; syntax and showing me how to apply it to write type signatures)

-fno-monomorphism-restriction

And if you don't like type signatures, here's what it looks like running without the monomorphism restriction:
dewdrop /tmp % ghci -fno-monomorphism-restriction
___ ___ _
/ _ \ /\ /\/ __(_)
/ /_\// /_/ / / | | GHC Interactive, version 6.6, for Haskell 98.
/ /_\\/ __ / /___| | http://www.haskell.org/ghc/
\____/\/ /_/\____/|_| Type :? for help.

Loading package base ... linking ... done.
Prelude> let r = 25
Prelude> 2 * pi * r
157.07963267948966
No surprises.

helping the newbies

Clearly, my explanation needs to be fixed. I just need to figure out the right way to do it though. I really don't want to get too technical (the reader doesn't even know about types yet!), but I'll need to avoid lying to the reader. It's already bitten two users, and it took me one of my readers typing in this text for me to figure out what had happened:
You might be thinking that this won't work--isn't 5 an integer, and therefore 5^2 also an integer? And didn't we just get an error trying to multiply pi by an integer?. What's going on is that when you "let r = 25", the "r" you get is more restricted than using the literal string "25" or 5^2. Try :t r and :t 5^2 and see the difference

I'm not entirely satisfied with this attempt (sorry), and want to deal with the situation more gracefully. Just don't know how to go about it yet.

knowing, Knowing and poly/mono


Oh a word about the scary name 'monomorphism restriction'. I find it curious that I should have found that name scary for so long. I mean, for the longest time, I've told myself that I liked 'polymorphism' right? So how difficult would it have been to do a little etymology and notice that 'monomorphism' sounds exactly like 'polymorphism', except that you replace the 'poly-' (many) by 'mono-' (one). By the right, the two words have equivalent scariness! But for some reason, my brain somehow refused to recognise the fact. Instead, it associated one word with warm fuzzies and the other word with huh-does-not-compute.

Otherwise, one thing I found interesting about this is how you can simultaneously (a) hold a piece of knowledge and (b) not apply it consistently. For example, when I had written that module, I knew that numbers could be any Num a (and that you could do fun things making up crazy implementations of Num), yet at the same time as I was using this knowledge (I told myself 'true, but let's not talk about that now, no point confusing the newbies'), I can completely failed to apply that knowledge, because I went back and reflexively treated 25 as an Integer, probably due to all that freshman OCaml teaching. You know something, but you don't Know it.


2007-07-05

mediawiki code projects

Three more projects to practice your Haskell with, and produce something useful while you're at it:
  1. a mediawiki writer for Pandoc (should be a piece of cake)
  2. a mediawiki reader for Pandoc (perhaps less easy, note that there is also some HTML to deal with)
  3. a mediawiki template engine : given a set of mediawiki pages on the local filesystem, convert mediawiki input into mediawiki output, with all templates interpreted
My super-seekret reason for suggesting these projects is so that we can one day convert the Haskell wikibook to LaTeX, or something else, and produce a nice PDF. Naturally, it would also be useful for the other wikibooks, many of which have crappy PDFs, or none at all. But that's not for you to worry about :-)... just have some nice exercises to play with.

(#3 might be a bit of work... and also, it's not clear that this is exactly what we want for converting wikibooks. It seems that the point would not be to expand the templates, but to convert them to something else. If I have a template called HaskellExercises, I don't want to expand it to a bunch of div tags or whatever; I want to convert it to something else)


2007-06-16

#haskell-books channel

Created on apfelmus's suggestion. Should provide a place for writers of Haskell books, tutorials, blogs, teaching materials of all sorts. We mostly had the wikibook in mind, but figured that others might like to join in on the fun. Real World?

Maybe we should host an annual monad tutorial contest or something, each year judging on different criteria, like "most creative use of tuna fish".


2007-05-18

risk and recursion

Lately, I've been playing a bit of correspondence Risk with some childhood friends. The good thing about correspondence Risk, when you're scattered across twelve timezones is that it is inherently self-limiting. You are forced to wait your turn every day. Well, that was my hope anyway, but it turns out that things are not quite that simple. The problem is that though you may well your turn, nothing is stopping you in the meantime from thinking about World Domination instead of doing something useful.

But maybe something useful just came out of these daydreams. I was thinking that Risk might be a good tool for teaching programming techniques. For example, it seems calculating dice roll outcomes would a rather nice example for teaching recursion and dynamic programming. This is something we typically do with factorial and fibonacci, but for some students, that might get a little boring. Perhaps dice rolls aren't all that exciting either, but maybe you could sell the Risk angle an awaken your audience's inner ten year old. Maybe you could sell this as part of a bigger package... in this class, we'll be putting together our own Risk implementation, with fancy graphics and everything.

The idea is that you want to ask your program "if the attacker has 37 armies and the defender has 10, what is the most probable outcome and its probability (assuming that each side uses as many dice as possible)?"

My belief is that there is no way to calculate this 'instantly' and without computing all possibilities. You would have to basically crunch through each one of the (a * d) eventual outcomes. (anybody with halfway decent math skills want to confirm that?)

One idea you might able to show with this is just plain simple recursion (although you probably want to start with a simpler example first). So I've got 37 and 10, and if I need the expected outcomes of 37/8 (attacker wins), 36/9 (both win one), and 35/10 (defender wins), I could just factor in the probabilities of getting those.

But I thought was interesting was that you could show that there is some redundant computation going on here. You start at 37/10, but then you go into
37/10
37/836/935/10

which in turn expands into
37/10
37/8
36/9
35/10
37/6
36/5
35/836/7
35/8
34/935/8
34/9
33/10

Here, we are recalculating the scenarios 36/7, 35/8 and 34/9. What happens if we turn the crank some more? If I'm not mistaken, the naive algorithm would have to do 3^n calculations (loosely speaking), when really we shouldn't be doing any more than n^2.

I suppose what you'd really want is to have some kind of record of all the outcomes you've already computed. I'm not sure how it would work out code-wise or how you'd shift all those weights around (and if you are interested, I do invite you to cook up a quick implementation, RiskBuzz). I will observe, however, that this table could make it simple to turn around and ask a slightly more involved question, like "ok, so what are the three likeliest outcomes and their probabilities?"


2007-05-01

haskell wikibook now featured

Spot the lambda?

Haskell :: Functional Programming with Types



Haskell :: Functional Programming with Types is now a featured wikibook, which means that it will be rotated on to the front page on a regular basis.

There are around 40 books on the site that have this distinction, so if you don't see the Haskell book on the front page, try again in another hour or so.

Write Yourself a Scheme in 48 Hours


Note that the wikibook version of Write Yourself a Scheme in 48 Hours has also been featured for quite some time. Yay, Johnathan! It's not on the front page yet, but should be making its way into the rotation at some point. Its blurb is
as follows:
In this advanced Haskell tutorial, we will implement a significant subset of Scheme together. We assume no prior knowledge; however, we will be going fast. So if you're feeling ambitious, why don't you Write Yourself a Scheme in 48 Hours?


2007-04-20

Haskell wikibook blurb

The wikibooks project has a 'featured book' concept, in which the best books of the project are prominently displayed on the front page. The Haskell wikibook has been nominated to be listed as one of these featured books. Votes are positive so far, but nothing official yet. In the meantime, all wikibook authors are being encouraged to put together an advertising blurb for the front page.

Here is my attempt. Can you make it better? Please feel free to post ideas on this blog, or on the wikibook talk page.

Haskell is a functional programming language with a state of the art type system. This book will introduce you to computer programming with our language of choice. It is friendly enough for new programmers, but deep enough to challenge the most experienced. Come stretch your mind with us!


(I'm not over-selling am I? I'm always worried about that)

Oh and the minimalist logo is just something I threw together (public domain, of course). Not married to it, just looking for something better than the current one.


2007-01-06

haskell wikibook print version

Just a quick note to mention that the wikibook's print edition is now automatically generated by a script. 90ish lines of what I hope to be reasonable-looking Haskell code. It should make it easier to keep that print version synched up.


2006-12-27

the Haskell metatutorial

Thanks to ndm for so clearly articulating the idea. Here is my attempt at implementing the Haskell metatutorial. Please add your stuff or even just expand the guide tree. Embrace the explosion of tutorials. Make something useful of it.


15:05:09 < AStorm> YAHT leaps a bit too far for me. I'd like something complete but less steep.
15:05:47 < metaperl> YAHT is probably as good as it gets INHO
15:05:49 < metaperl> IMHO
15:06:01 < uccus> there should be a grant unification project for Haskell tutorials
15:06:02 < metaperl> the "algorithms" book is not bad either
15:06:26 < kowey> uccus: the wikibook attempts to remix heavily
15:06:28 < uccus> *grand [blushes]
15:07:01 < kowey> we've got yaht, write yourself a scheme, jeff newbern's stuff, some original content, all mashed up and duct-taped together
15:07:03 < ndm> what i would like is a meta-tutorial
15:07:14 < ndm> a list of questions about haskell, what does this do, do you understand this etc
15:07:26 < ndm> and if you say no, it points you at a tutorial which explains it
15:07:28 < uccus> well, mashed up and duct-taped is not good
15:07:41 < ndm> is there a tutorial on pattern matching, for instance?
15:07:44 < uccus> aah. yes. I agree with ndm
15:07:47 < kowey> we could use some heavy editing
15:07:48 < ndm> which covers ~, !, @ etc
15:08:12 < kowey> right, me too... it's like the malcolm gladwell stuff
15:08:17 < uccus> the wikibook can do that
15:08:31 < kowey> many "right" flavours of coffee, pepsi; extra-chunky tomato sauce, etc
15:08:40 < uccus> it's divided into sections... they can contain links to complete tutorials
15:08:59 < uccus> everyone has a different style of tutoring you know...
15:09:05 < kowey> i agree
15:09:16 < kowey> the wikibook right now is newbie-oriented
15:09:28 < kowey> but we could steer it towards choose-your-own-adventureness
15:09:43 < uccus> kowey: the wikibook right now has different steams for newbie/advanced(?)
15:09:45 < kowey> comments on the discussion page on how we could implement this would be quite welcome
15:09:55 < kowey> we have two tracks, newbie and advanced
15:10:16 < kowey> although the advanced track assumes you've basically just gotten through the newbie track... it tries to be a friendly "advanced"
15:10:19 < uccus> yes, but shouldn't there be more?
15:10:39 < uccus> tracks?
15:10:41 < kowey> well, it's got two tracks in terms of material, one track in terms of style
15:11:04 < kowey> what ndm is talking about is having multiple tracks in terms of style (well... style, level)
15:11:10 < uccus> I mean, the grand Haskell wikibook should contain things that are really advanced
15:11:25 < uccus> like tutes for gtk2hs...
15:11:37 < ndm> kowey: i more meant accepting there will be loads of tutorials, but trying to point people at those which will teach them something new
15:11:42 < uccus> *that* should be called advanced
15:11:44 < kowey> i tend to suspect that's more the Haskell wiki's job
15:12:13 < kowey> although there is http://en.wikibooks.org/wiki/Haskell/GUI
15:13:07 < uccus> aaah. thanks kowey. that's enough I think.
15:13:33 < kowey> ndm: i think we're saying the same thing, although i'm speaking horribly imprecisely


2006-12-22

Denotational semantics

Apfelmus from IRC just wrote what looks like a very nice chapter on denotational semantics. I am reading it now and learning lots. Why not check it out and post comments on the talk page? I'm sure he'll appreciate any comments the Haskell community might have, or anyone with an interest for that matter.

Thanks, afpelmus; what a great Christmas present!


2006-12-10

rewriting PLEAC Haskell?

One complaint I have heard about the Haskell cookbook is that it is rather unidiomatic and thus not very helpful for people trying to learn Haskell. For example, one particularly shocking thing the implementation does is to shadow (.) operator to make more "object-like": o . f = f o (reverse dollar? euro?). This leads to snippets of code which, as one of the wikibook commentors put it, are barely recognisable as Haskell:
s''' = s1.split " ".reverse.join " "


PLEAC Haskell in its present form is not very suitable for educational purposes, but what if the Haskell community ran through and cleaned it up? Only the first two chapters are implemented anyway, so it doesn't seem to be all that much; the only substantial thing to rewrite perhaps being in soundex code. I personally cannot invest any time in this, being already behind in other projects like darcs and wxhaskell, but it might be a fun project for Haskell enthusiasts, or even yellow-belt Haskellers trying to come to grips with the language.

If interested, you should probably subscribe to their mailing list and maybe bounce around some ideas on the Haskell café. Another thing to consider is contacting the original author Yoann. It would be good to get him on board, maybe with a little gentle persuasion. I mean, he probably thought it was a good idea to make the language more recognisable to newcomers. Nice thought... but maybe he would now agree that newbies would be better off with more idiomatic Haskell.