Try Haskell: An interactive tutorial in your browser
tryhaskell.org
tryhaskell.org
Bear in mind I'm pretty handy with obscure obfuscated by default things like RPL, Forth and Perl and occasionally common lisp.
How come?
Syntax feels slightly horrid. Doesn't seem to visually or syntactically scale well with the size of the problem at hand. Some of it is plain ugly (records). It's harder than the others resulting in more head scratching. Debugging is slightly painful.
These are all IMHO.
To be fair, I'm going to do the tutorial again this afternoon.
Look at List.hs (sort/sortBy) for what I mean:
http://hackage.haskell.org/packages/archive/base/latest/doc/...
I might get it if I keep trying.
(ironically I did an engineering degree which was rather maths heavy so I should get this).
Haskell can just take some time to get used to. The code is laid out differently and the use of curried functions and point-free styles can throw you off coming from imperative code.
An example: almost every FP course has the students define the Maybe datatype with its accompanying functions. In Haskell Maybe is an instance of Monad, but you don't need to know that to use or make Maybe, it just turns out that the Maybe solution is in that class of Monads.
I gave this book to a lot of programmer friends, and most were very enthusiastic after finishing the book. Even if you never use Haskell in the real world, learning its abstractions makes you a better programmer (and sometimes annoyed by the lack of type system features in other languages ;)).
> map reverse
No instance for (GHC.Show.Show ([[a0]] -> [[a0]]))
arising from a use of `M1690418375.show_M1690418375'
Possible fix:
add an instance declaration for (GHC.Show.Show ([[a0]] -> [[a0]]))
Hmm.... > :t map reverse
:: [[a]] -> [[a]]
> show (map reverse)
No instance for (GHC.Show.Show ([[a0]] -> [[a0]]))
You can't show functions. Pass an argument: > map reverse ["test","this"]
=> ["tset","siht"]> let f = map reverse
> f [[1,2,3], [6,7,8]]
EDIT: scratch the "let" example (thanks nandemo), tryhaskell.org doesn't support that. my bad!
Note that in "let t=bar in foo" the scope of t is restricted to foo, so the example above still doesn't work.
[1] http://www.reddit.com/r/haskell/comments/b58rk/try_haskell/c... ([deleted] = Chris Doner)
IMHO the tryhaskell expose more or less only simple pure functions and I doubt that anyone with a real interest in haskell will get any substantial out of it. However if one is completely new to programming maybe TryHaskell and these 6 short lessons have a value.
Incidentally, Chris Doner has been producing far more exciting things like Fay, so I'm not gonna complain about TryHaskell.
Try map reverse ["abc", "123"] instead, which it does know how to print.
This looks like the kind of thing I get when my C linker has horribly choked on my code, what is the benefit of displaying: M1690418375.show_M1690418375 to the user? What should I do with that piece of information?
How do I 'add an instance declaration for (GHC.Show.Show ([[a0]] -> [[a0]]))'? I'm guessing that this is basically "suggesting" I implement printing for all functions? Or just for map? I'm not sure. I'm sure I'm not doing it, and it may well not even be possible?
(i) use ghc and ghci. TryHaskell isn't actively mantained AFAIK.
(ii) if you find a cryptic error message, first google it and learn the immediate fix, without trying to understand all the details. Of course, eventually you'll have to learn the details, but there's no reason it should be a blocking issue in the beginning.
In any case this is my short-ish, inaccurate version of "the details":
1. In the interpreter, there's an implicit "print foo" when you type "foo".
2. "print foo" expects a foo of any type t as long as t is an instance of the typeclass Show, meaning there must be a show function associated with t that turns t's into Strings. Roughly, that would be as if we had a Java where the method toString (=show) is not part of Object, but rather of an interface Showable, which not all classes have to implement.
3. In Haskell, it was decided that function types shouldn't be instances of Show because they don't have a sensible show implementation. In theory you can have a show implementation that prints "this is function" for all functions, but that's of limited usefulness.
4. The compiler's error message is just an instance of a more general message: a value foo is used in a place that expects a type that's an instance of SomeTypeClass, but foo turns out to be of a type T that isn't. For instance, if you try this on ghci:
> 'a' + 'b'
you'll get a similar error message, because '+' expects 2 arguments of a type that's an instance of typeclass Num, but 'a' and 'b' are of type Char which is not a Num in Haskell. In theory, the compiler could be "hardcoded" to print a special error message when SomeTypeClass happens to be Show, such as "can't print that type". That would be easier for beginners, but would add some complexity to the compiler.5. The "M1690418375.show_M1690418375" thing is probably an artifact of the way TryHaskell was implemented. In ghci, you simply get this instead:
arising from a use of `print'
I hope this helps. > let foo = map reverse
As the error message "clearly" says, the result "map reverse" is a function, which doesn't have a printed representation. You might think that all objects would at the minimum have a default printable representation as "[Object 0x011432542]" or something, but they don't. As always with haskell, the idea is to catch mistakes at compile time: in this case, mistakes where you wanted to show something meaningful to the user, but forgot to define how that kind of object should be printed.Well done, that was tricky syntax. You used the (:) function. It takes two values, some value and a list, and constructs a new list out of them. We call it 'cons' for short.
No it's not:
> 'a' : [] => "a"
[1] Which incidentally is a reason to avoid using it for anything serious. Text is the better representation of text, and ByteString is better for everything else.
> 'a' : "" => "a"
Because that's what you did.