|
|
>> Ah, right, so it's overloaded but that's not shown in the article?
>
> Yup, it is in the source code however.
Ah, OK. I thought it was just a typo or something...
>> (BTW, I thought printf() was only for C, not C++?)
>
> Well it is for C, but anything you can do in C you can do in C++. Not
> that it's a good idea though...
Ah yes, C++ is a superset of C. But I was thinking (hoping?) that in C++
you have something less hellish than prinf() to play with...
>> Did the Haskell version look "readable"?
>
> Not really, I tried to add some to your code to show what I meant with
> the other evaluate function, but I couldn't work out what was going on!
No, Haskell doesn't support overloaded functions, so you'd have to make
some moderately radical (oxymoron?!) alterations to make it work.
> Seems logical, but without thinking about it too much, how would you
> keep track of the state of the system while it's running?
Ah, grasshopper, you are still thinking in imperative terms. ;-)
A true Haskeller would define a notionally infinite list which
notionally contains the entire state of the system at every future point
in time. Examining the elements of this list causes the integration to
actually be performed, and assuming you let go of the start of the list,
the GC will delete each state after it has been calculated.
In other words, define an infinite list, and then map some monadic
function over it which displays the state of the screen or dumps it to a
file or otherwise "does" something with it. And the result will be more
or less like this C++ example.
Now, if you want to use *user input* to alter the integration as it
proceeds, then you must take an somewhat different approach. (See below.)
> Are you
> basically saying that variables are write-once in Haskell?
You *could* put it that way. It would be more correct to say that a
variable is *defined* as having a specific value in Haskell. Consider this:
let node1 = Node {next = node2, prev = node4}
node2 = Node {next = node3, prev = node1}
node3 = Node {next = node4, prev = node2}
node4 = Node {next = node1, prev = node3}
in ...
As you can see, it's not so much that you can only assign once to a
variable, it's that you are *defining* what a variable's value *is*. The
compiler will chase dependencies - even circular ones - and resolve them
for you, figuring out what order to initialise everything and so forth.
(You can't really speak of assigning several values to the same variable
"one after the other" because [pure] Haskell function don't have any
notion of "time".)
> So I couldn't do something like:
>
> currentState = Integrate(currentState);
No, you couldn't.
You could, however, write
animate state = do
dispaly state
let new_state = integrate state
animate new_state
which will display the initial state, call your integrate function to
compute the next state, display that state, and so forth. (This method
*does* allow you to accept user input and do something different based
on what the user input is.)
A third way would be to use explicitly mutable state - something like this:
state <- takeMVar my_state
writeMVar (integrate state)
But there's no particular advantage in doing that here, and it just
takes more typing to write out.
--
http://blog.orphi.me.uk/
http://www.zazzle.com/MathematicalOrchid*
Post a reply to this message
|
|