I'm tired of fighting with ENTERPRISE languages. I want to learn Haskell. The question is, where do I start?
I'm not completely ignorant of programming language theory -- I read http://mitpress.mit.edu/catalog/item/default.asp?ttype=2&tid=8184 several years ago -- but the math is a bit rusty. I've tried a few Haskell ``introductions'' but they were more philosophical wanking about the beauty of monads and other abstract bullshite than an instruction on how to program in Haskell. In short, help.
Name:
Anonymous2008-07-18 9:29
philosophical wanking about the beauty of monads and other abstract bullshite
Accurate characterization of Haskell.
If you just want to get shit done, use Cinnamon Lasp. If you want to get shit done with some beauty, use the Algorithmic Language Scheme. If you want to learn type theory before writing trivial programs in clunky ways while getting raped by the type checker, use Haskell (or ML, which is slightly less bad).
Example of rape by the type checker:
Let's write a function that takes two arguments, adds them and returns the negative of that. I'll write it in point-free style because don't want to specify trivial details like arguments.
Well, that was very helpful. After some experimenting I realize that the . only composes for one argument, so you have to use it twice somehow. This is an example of how automatic currying will bite you in the ass. After some experimenting/googling/digging my memory:
addNeg = (0-) `((.).(.))` (+) ERROR file:{Hugs}\packages\hugsbase\Hugs.hs:7 - Syntax error in expression (unexpected `(')
So the syntax is raping us this time, let's get rid of the ``.
addNeg = ((.).(.)) (0-) (+)
Well, that finally worked. But ((.).(.)) is pretty fucking ugly. So let's create a function compose that takes a number of times to compose, and returns a function that composes that much.
compose x = foldl (.) ($) $ replicate x (.) ERROR file:{Hugs}\packages\hugsbase\Hugs.hs:6 - Type error in application
*** Expression : foldl (.) ($) $ replicate x (.)
*** Term : foldl (.) ($)
*** Type : [((c -> a) -> c -> b) -> (c -> a) -> c -> b] -> ((c -> a) -> c -> b) -> (c -> a) -> c -> b
*** Does not match : [(a -> b) -> (c -> a) -> c -> b] -> ((c -> a) -> c -> b) -> (c -> a) -> c -> b
*** Because : unification would give infinite type
... thanks a lot. Maybe my type theory is too weak or I need to use some wacky Glasgow extensions with ghc, but I think that writing functions with a (return) type dependant on their argument(s) is impossible in Haskell. So much for abstracting things.
Meanwhile, in Scheme I do
(define add-neg (compose - +))
and it just works. The only thing to note is that while compose is not in RxRS (it can easily be defined with its primitives), it may be provided by your implementation (e.g. PLT).
Name:
Anonymous2008-07-18 10:38
>>6
Why the hell are you using Hugs? GHCi is superior in every way.
If you are looking for dependent types, you're certainly not gonna find a pretty implementation in Haskell. Try Epigram, or something.
Name:
Anonymous2008-07-18 12:25
>>20
It's slightly better, but still sexual harassment.
GHCi, version 6.8.2: http://www.haskell.org/ghc/ :? for help
Loading package base ... linking ... done.
Prelude> let addNeg = (0-) . (+)
<interactive>:1:13:
No instance for (Num (a -> a))
arising from a use of `-' at <interactive>:1:13-16
Possible fix: add an instance declaration for (Num (a -> a))
In the first argument of `(.)', namely `(0 -)'
In the expression: (0 -) . (+)
In the definition of `addNeg': addNeg = (0 -) . (+)
Prelude> let addNeg = (0-) `((.).(.))` (+)
<interactive>:1:19: parse error on input `('
Prelude> let addNeg = ((.).(.)) (0-) (+)
Prelude> let compose x = foldl (.) ($) $ replicate x (.)
<interactive>:1:44:
Occurs check: cannot construct the infinite type: a = a1 -> a
Probable cause: `.' is applied to too few arguments
In the second argument of `replicate', namely `(.)'
In the second argument of `($)', namely `replicate x (.)'
Prelude>