Return Styles: Pseud0ch, Terminal, Valhalla, NES, Geocities, Blue Moon.

Pages: 1-4041-

/prog/ advice series: Haskell

Name: Anonymous 2008-07-18 0:23

Dear /prog/,

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: Anonymous 2008-07-18 0:38

GET OFF YOUR TOY LANGUAGES AND GO PROGRAM IN SEPPLES.

Name: Anonymous 2008-07-18 0:55

Read SoE.

Name: Anonymous 2008-07-18 1:03

OP here, I followed >>2's advice and my ENTERPRISE penis grew by 2x almost immediately. Now I write all my program logic using template metaprogramming. I haven't used a while loop in weeks, and my compilation times have never been longer! Thanks >>2!

Name: Anonymous 2008-07-18 5:27

Read YAHT.

Name: Anonymous 2008-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.

addNeg = (0-) . (+)
ERROR file:{Hugs}\packages\hugsbase\Hugs.hs:5 - Unresolved top-level overloading
*** Binding             : addNeg
*** Outstanding context : (Num b, Num (b -> b))


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: Anonymous 2008-07-18 9:35

>>6
Score:5, Insightful

Name: Anonymous 2008-07-18 10:38

>>6
Why the hell are you using Hugs? GHCi is superior in every way.

Also, why didn't you try  addNeg = (.) negate . (+) ?

If you are looking for dependent types, you're certainly not gonna find a pretty implementation in Haskell. Try Epigram, or something.

Name: Anonymous 2008-07-18 10:52

>>8
If you are looking for dependent types, you're certainly not gonna find a pretty implementation in Haskell. Try Epigram, or something.
This is what static typing faggots actually believe.

Name: Anonymous 2008-07-18 10:57

>>9
Dynamic typing faggots might believe it too, since it is the truth.

Name: Anonymous 2008-07-18 11:07

>>10
Think about what you just wrote. Think.

Name: Anonymous 2008-07-18 11:16

Name: Anonymous 2008-07-18 11:18

>>12
YES, I DO VERY WELL KNOW WHAT DEPENDENT TYPES MEAN. ARE YOU REALLY THIS FUCKING STUPID, OR HAIB?

Name: Anonymous 2008-07-18 11:20

>>13
If you do, then you must be trolling, because I don't know where you're getting at. Why don't you enlighten me?

Name: Anonymous 2008-07-18 11:22

>>14
You've been seriously off track on several levels since >>10.

Name: Anonymous 2008-07-18 11:24

>>15
Yes? Tell me why.

Name: Anonymous 2008-07-18 11:32

>>8
I use Hugs because
1) it doesn't waste hundreds of megabytes on my hard drive. It's not a real problem now that I have 1TB, but until recently I was stuck with 20GB.
2) it is good enough for me. If I was a hardcore Haskell programmer, I'd probably use ghc.
3) ghc fails on recursive types, see http://www.haskell.org/ghc/docs/latest/html/users_guide/bugs.html

I didn't try that because
1) the syntax makes no sense to me
2) my train of thought was ``compose twice -> double compose''.
After reading http://www.haskell.org/haskellwiki/Pointfree I think addNeg = (negate .) . (+) is the accepted syntax. It's nicer on the eyes, but I still think it's not abstracted enough.

Dependent types might help, but for me the real solution is to not use static typing.

Name: Anonymous 2008-07-18 11:33

Real World Haskell:

http://book.realworldhaskell.org/beta/index.html

Latest and greatest Haskell book.

Name: Anonymous 2008-07-18 11:42

>>17
Alright, fair enough.

Name: Anonymous 2008-07-18 11:46

>>17
GHC's type checker doesn't rape you, though. Its messages are clear enough to find the error.

Name: Anonymous 2008-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>

Name: Anonymous 2008-07-18 12:40

FUCK HASKELL IN THE ASS!!!

Name: Anonymous 2008-07-18 12:45

Prelude Data.Function> (on (+) negate) 1 2
-3

Name: Anonymous 2008-07-18 12:50

Operator precedence? Typed lists?  Might as well be using Sepples.  Back to Scheme I go.
[True, False, "testing"]
(list #t #f "testing")

Name: Anonymous 2008-07-18 13:00

>>> [True, False, "testing"]
[True, False, 'testing']

Name: Anonymous 2008-07-18 13:07

>>25
Go suck Guido's expressive cock

Name: Anonymous 2008-07-18 13:07

>>26
I will, along with my job.

Name: Anonymous 2008-07-18 14:04

>>21
You'll be fine after some counseling.

Name: Anonymous 2008-07-18 14:05

>>6
((.).(.))
The triple-tit operator?

Name: Anonymous 2008-07-18 14:59

_|_

Name: Anonymous 2008-07-18 16:28

Read YAHT.

Name: Anonymous 2008-07-19 8:53

Read YHBT.

Name: Anonymous 2008-07-20 1:00

Read a book about haskell

Name: Anonymous 2008-07-20 2:52

>>33
Which one?

Name: Anonymous 2008-07-20 3:11

>>34
Like there are that many to choose from.

Name: Anonymous 2008-07-28 10:17

>>6

Don't do it point-free then fagtard. I'm sorry but it's a manufactured problem.

Name: Anonymous 2008-07-28 20:17

>>36
Don't do it in Haskell then fagtard. I'm sorry but it's a manufactured problem.

It's an example. I'd love to show you how the type system screws you in useful Haskell programs but there are no useful Haskell programs.


In unrelated news, thanks to the monomorphism restriction η-reduction doesn't always work in Haskell.

Name: Anonymous 2008-07-28 21:07

>>37
Go back to formal language theory, smartass

Name: Anonymous 2008-07-29 5:45

>>37
In unrelated news, thanks to the monomorphism restriction η-reduction doesn't always work in Haskell.
Hurrrrrrr

Just give your function an explicit type signature (which you should be doing for all top-level values anyway) or turn the MR off (usually not a good solution).

But >>36 is right. If you're going to complain, then at least complain about real problems like the clunky record system, the stupid organization of the numeric type classes or the fact that fail is required for every Monad.

On a final note, I solve your composition problem by defining

(.:) :: (c -> d) -> (a -> b -> c) -> a -> b -> d
(.:) = (.) . (.)
infixr 9 .:


You can go further and define (.::) and so on, but I've never needed to (and I write quite a bit of Haskell).

Name: Anonymous 2008-07-29 11:07

>>39
You don't have to define fail for your monad if you don't want to. It defaults to "fail s = error s".

Name: Anonymous 2008-07-29 11:32

fail f = print "epic fail" >>= error f

Name: Anonymous 2008-07-29 11:42

>>40
fail breaks the monad laws.

Name: Anonymous 2008-07-29 13:49

>>42
Why?

Name: Anonymous 2008-07-29 16:32

>>43
not enough anii to hax

Name: Anonymous 2008-07-30 9:57

>>44
Thread over, sadly.

Name: Peyton `Osama` Jones 2008-07-31 16:10

Name: Anonymous 2008-07-31 16:28

Name: Anonymous 2008-07-31 17:34

>>47

VIRUS!! DON'T CLICK THAT LINK, FOLKS!

Name: Anonymous 2008-07-31 20:26

>>47
I left Ubanto for Debian over an autoconfig issue as well, but my wireless actually works. I guess Randall's family suffers from inbreeding.

Name: Anonymous 2011-02-10 1:26

>>6,8,21
here's the real solution to that problem:
instance (Num a, Eq a) => Num (x -> a) where
    fromInteger = const . fromInteger
    f + g = liftM2 (+) f g
    f * g = liftM2 (*) f g
    f - g = liftM2 (-) f g
    negate = (negate .)
    abs = (abs .)
    signum = (signum .)

addNeg = -(+)

Name: Anonymous 2011-02-10 5:20

>>51
Archeology ahoy!

Name: Anonymous 2011-02-10 5:22

>>52
* Archaeology

Name: Anonymous 2011-02-10 8:57

>>53
The logy of archaea

Don't change these.
Name: Email:
Entire Thread Thread List