|
![](/i/fill.gif) |
>> data MinHeap x = Node x (MinHeap x) (MinHeap x) | Null
>
> This is much cleaner than anything you'd see in Erlang, fwiw. Lots of
> Erlang syntax for passing around functions (or lambdas) is so
> heavy-weight that making (say) a list of lambdas as a bound variable in
> another lambda you pass somewhere winds you up with so much nesting and
> syntax cruft you're almost required to split it into a different function.
I've seen a lot of programming languages described as "functional".
(Lisp, Erlang, Clean, etc.) But I have yet to see any language that
works the way Haskell does. Lots of languages that allow you to program
in a functional way (hack, assembly language can do that!), but none
that really facilitate this very strongly.
Haskell is a "pure" functional language, in the same way that Eiffel is
a "pure" OO language. It seems that most "functional" languages aren't
very pure. Conclude what you want about that...
> I've found there's a couple of annoyances with functional programming
> (at least in Erlang):
>
> 1) Every control-structure is out of line. You can't really do a while
> loop without having the body show up somewhere else, and almost always
> needing a name. (I suspect Haskell's lazy evaluation makes this much
> less of a problem, since you can just use something like fold over a
> multi-gigabyte file and not worry about bombing out.)
Yeah, typically in Haskell you'd either do something like takeWhile to
grab just the data you want, or write a custom loop yourself.
> 2) There's no simple way to pass private information around. If I'm
> doing some process that is (say) reading thru a big file, processing
> hundreds of lines a second but still taking dozens of minutes to run, if
> I want to put in a counter to print how far along it has gotten every
> 1000 lines (so I know it's working), it's a major pain to pass and
> update that everywhere, interfering with all kinds of things (including
> the caller of the function needing to pass the initial counter).
State monad.
Wanna pass more information around? Change the state data structure.
> 3) If you have a functionality that has a complex control flow, you
> basically wind up writing it as a bunch of separate functions with tail
> calls routing things around, like a state machine.
Take a look at Parsec.
It's a parser library, and the usual way to implement a parser is with
some kind of state machine. However, Parsec uses a parser monad to
implement complex flow control (choice, iteration, back-tracking, error
handling, etc.)
For many kinds of complex flow control, you can structure the algorithm
either as a monad or maybe an arrow. (Every monad is an arrow. Some
arrows are monads.)
The really killer decision is finding exactly the right way to abstract
the task you're trying to perform. This is critical in any language, but
can be particularly non-obvious in Haskell. And usually, once somebody
shows you a better solution, you wonder why you didn't think of it
yourself... ;-)
> Every time one you
> change one of those to track something new, you have to track down every
> call and pass the new thing.
In that case, it's probably best to define the information you're trying
to keep track of as a data type and just add/remove fields as required
when the design changes. That way you only pass around a single parameter.
--
http://blog.orphi.me.uk/
http://www.zazzle.com/MathematicalOrchid*
Post a reply to this message
|
![](/i/fill.gif) |