For all the haskell fans out there:

let f = (.).(.)

One of the tasks for my homework in Informatics 2, which is basically Haskell lab, is to evaluate this statement, and figure out what the function declaration for it is. In other words, f::x->y->z->…

Okay. Seriously, what the fuck? First of all, this sort of evaluation is not something that ever needs to be done by hand. If you’re in an environment where you can compile haskell, you’re in an environment where you can open up GHCi, type the following code:

let f = (.).(.)
:t f

…and the compiler will give you exactly the precise declaration for the function. So it’s a complete waste of time to try to do this by hand. But more importantly, who the fuck writes a function like this? What, are they afraid of running out of pixels if they write it out? Like, here’s another one.

g = (.) map

…Or, in non-fucking-stupid-o-vision:

g function1 function2 list = map (function1 list).function2

Which, while still a fucking mess, is at least somewhat understandable. I couldn’t even fucking tell you what this would look like for the function above. This is a complete and utter waste of everyone’s time .

I’m a little disappointed in your egregious begging of the question in your OP.

You seem to be under the misapprehension that there exist fans of Haskell.


Yeah, seriously. Fuck this language.

They’re asking whether you understand type inference.

I haven’t read the bible in a while and am a little fuzzy on the details. Did God create GHCi on the eighth day after resting on the seventh or did he hand it down to Moses along with the ten commandments?

Okay, I know what the two . inside the () are, but what’s the . in the middle? Is that like a necklace or something?

Haskell: Gee, Mrs. Cleaver, that sure is a nice dress.

That Haskell?

Your coding looks like boobies.

But they hang down around the belly button.

Oh, it’s a belly button. :frowning:

At the risk of attempting a non-boob-related answer (I know some Haskell, but not a lot, and certainly not enough):

“.” composes two functions, so I’d expect its signature to be something like (a -> b) -> (b -> c) -> (a -> c)

The notation seems to want to compose two composes, so I’d think something like (a -> b) -> (b -> c) -> (c -> d) -> (d -> e) -> (a -> e) or something.

I seem to recall that Jragon actually knows Haskell, so he might come in with a better answer.

Edited to add: Couldn’t you use Haskell’s infix notation to write the same thing as “(.)(.)(.)” (aka Total-Recall-notation)?


“Gee, Eddy, I didn’t know you could type… I thought all you knew how to do was be a jerk to guys!”

Eddy Haskel: :dubious: :mad:

I think the point of this exercise is that people sometimes write garbage source, so you need to be able to recognize it. Like, if I was teaching some form of C, I would reveal on the last day that there exist these foul goto things and jump labels: and some assholes use them but you, my students never, ever should, just be aware that this garbage exists, so that you are not flummoxed when you see it.

When I was first learning OO (C++ in like 1993 or so), I had a final exam that consisted of the most insane spaghetti garbage the instructor could devise, chock full of GOTOs and the like…and we had an hour to untangle it and rewrite it. I think it went from 300 lines to 14 or something ridiculous like that.

I recall he told us something like “If there’s only one thing you take away from this class, it’s to make sure you never have to to that–with your own code, at least–again.”

This brings back memories of a PL/I assignment where it was necessary to use an ON ERROR block. We discovered to our horror that to continue operation after handling the error it was necessary to use a GOTO, otherwise the program would stop at the end of the block.

Naturally I labeled the line to be executed after the ON ERROR block HELL:

The function takes a function with two input parameters and boils it down to a function with one input parameter. It’s a total fucking mess, but an ingenious total fucking mess. Which is what really gets me. It’s not some mess of code made by some idiot looking for workarounds everywhere. To write something like this coherently, you’d have to be damn good at Haskell. And also terrible at writing good code, because writing it like that would be ass. Also, yeah, total recall notation is the same function. For those wondering, the header is:

f:: (b->c)->(a->a1->b)->a->a1->c

So yeah. Total clusterfuck.

That would be nice, wouldn’t it.

That doesn’t seem *so *bad as a signature. It looks like it’s just taking a function of two variables (a->a1->b) and a function of one variable (b->c) and creating the function that applies the latter to the result of the former (a->a1->c). I don’t see off hand how to get that from the boobs, but the signature itself doesn’t seem that bad.

OK, I’ll repeat: the point of the exercise is to demonstrate that you know how Haskell’s type inference works and that you understand polymorphism, as you have three occurrences of the same function all at a different type. Nobody writes Haskell like this in practice as it’s a completely contrived example used for teaching purposes. Further, no Haskell programmer is sitting with pen and paper trying to work out the type of an expression when GHCi exists, in the same way that no mathematician is sitting with pen and paper factoring polynomials when Mathematica exists.

Oh man, you reallllllly want to start a flame war, dontcha? :smiley:

I mean, I’m basically with Capt. Ridley’s Shooting Party here – the point of the exercise is to be difficult, to flex your brain bits around a fairly tricky but powerful abstraction. Obviously, when writing production code, you want to make it as straightforward as the circumstances permit, but often the whole raison d’être for exercises is to be abstruse.

I definitely cannot agree with you here. The first version is far more readable. There are no extraneous symbols to confuse the eye or create false impressions. This is perhaps demonstrated by the fact that your proposed reformulation doesn’t do the same thing and in fact does not even have the same type as (.) map. The point-free declaration of g is straightforward: it composes map with another function. That is, g f is the same thing as map . f . Your redefinition of g does something else entirely.