Hacker News new | comments | show | ask | jobs | submit login

I didn't like LYaHfGG.

Take this in p52 for instance:

maximum' :: (Ord a) => [a] -> a

maximum' [] = error "Maximum of empty list!"

maximum' [x] = x

maximum' (x:xs) = max x (maximum xs)

Now, you may think that implies that you could do something like this to print a string one character at a time:

rsoat (x:xs) = show x (rsoat xs)

Buy you can't. If you try that Haskell complains "The function 'show' is applied to two arguments, but its type 'a0 -> String' has only one...."

Fair enough, one might reason - you're just passing max two things when it wants one so we can do something like this:

rsoat [] = []

rsoat [x] = show x

rsoat (x:xs) = rsoat xs

But no, that just gets you the tail of your string because x:xs doesn't match x so it never prints the other bits.

What you may end up doing is something like this:

rsoat [] = []

rsoat [x] = [x]

rsoat (x:xs) = show x ++ (rsoat xs)

But that's still not really doing what you wanted to do in the first place. It's sticking all your characters into a string and then reading that string all at once. And it's not a particularly obvious solution either if you don't know the language.

This may seem a silly example. But what happens when, as is frequently the case, someone wants to retrieve the nth element of a list? (list !! n) Haskell, as learnt through Learn You a Haskell, can easily be expected to drive someone up the wall who starts asking such questions - it's not a whole bunch of fun to play with.




To be honest, it does not seem you did a very good job of reading the book. If you're rooted in imperative languages, it takes some effort. I read the book when I had already had some basic functional programming experience, so my experience might not be so representative, but I've heard quite a few positive reviews from people for whom it was the first introduction to FP.

You seem to start off from a wrong premise that the show function prints things. It doesn't - it simply converts whatever value (of type a) you give it to a String (provided a is an instance of the Show typeclass). So seeing that you already have a string, a function which converts things to strings will probably not be very useful.

> rsoat [] = [] > rsoat [x] = show x > rsoat (x:xs) = rsoat xs

> But no, that just gets you the tail of your string because x:xs doesn't match x so it never prints the other bits.

Uh, no. It doesn't give you the tail of the string, it gives you a list containing just the last element of the argument (if the argument's not empty), or the empty list (if the argument is empty) - which you can read directly from your definition.

Furthermore, " x:xs doesn't match x" doesn't make a whole lot of sense - it's not supposed to match x, it's supposed to match a non-empty list. Which it does, and the first element of such a list gets bound to the parameter x - but you do not use the parameter in your right-hand side of the definition, so you effectively discard it.

Note that both pattern matching and the Show typeclass (and the corresponding function) are discussed in the book prior to the minimum example.


> You seem to start off from a wrong premise that the show function prints things.

No, I know what it does. That's how the book describes it however:

"The most commonly used function that operate on instances of this type class is show, _which prints the given value as a string_"

> Uh, no. It doesn't give you the tail of the string, it gives you a list containing just the last element of the argument (if the argument's not empty), or the empty list (if the argument is empty) - which you can read directly from your definition.

I continually forget that tail means the rest of the thing.

> Furthermore, " x:xs doesn't match x" doesn't make a whole lot of sense - it's not supposed to match x, it's supposed to match a non-empty list. Which it does, and the first element of such a list gets bound to the parameter x - but you do not use the parameter in your right-hand side of the definition, so you effectively discard it.

We're far enough away from what each other are thinking that this just isn't worth talking about as written.

You've already matched your list to x earlier in the program so x:xs doesn't get a chance to run. You're not showing x and then falling through to pass xs to the function again and chopping the first element off of that to show - and so on.

> Note that both pattern matching and the Show typeclass (and the corresponding function) are discussed in the book prior to the minimum example.

This:

http://i.imgur.com/7NKReoL.jpg

is not a discussion of the show type class and corresponding function.


Fair enough, I don't have the printed version around. It's wrong on that point and I can see that it can be misleading. To their credit, here's the current formulation from the online version:

> Members of Show can be presented as strings. All types covered so far except for functions are a part of Show. The most used function that deals with the Show typeclass is show. It takes a value whose type is a member of Show and presents it to us as a string.

This is correct. Whether it qualifies as a proper discussion might be debatable, but since the particular typeclass is simple enough, and seeing that this appears very early in the book, it seems reasonable.

> You've already matched your list to x earlier in the program so x:xs doesn't get a chance to run. You're not showing x and then falling through to pass xs to the function again and chopping the first element off of that to show - and so on.

This is incorrect. Definitions are not really "executed" (or run) in Haskell; you simply replace the left-hand side of the definition with the right-hand side. You use the first definition (in file order) with a matching LHS. So in your example, the third definition for rsoat would be used for all lists with more than one element. So the "falling-through" as meant here is not what you get with, say, a switch statement in C.


>Now, you may think that implies that you could do something like this to print a string one character at a time:

I'm not sure how far you got after this point, but the problem is easily solved with a higher-order function:

    mapM_ print "blahblahblah"
Or if you don't like each character being quoted:

    mapM_ (putStrLn . return) "hello one at a time"
Or did you not want the characters on their own lines? In that case, you can do this:

    mapM_ putChar "horse raddish"
But why bother doing that when you can simply do this?:

    putStr "egg freckles"
>But what happens when, as is frequently the case, someone wants to retrieve the nth element of a list?

If you are frequently wanting to do this, you are probably doing something wrong. Haskell's lists are intended to be used as control structures, not indexed data structures. For those, you'll want an Array, Vector, IntMap etc.




Guidelines | FAQ | Support | API | Security | Lists | Bookmarklet | DMCA | Apply to YC | Contact

Search: