
On Sun, Dec 21, 2008 at 02:56:06AM -0700, Luke Palmer wrote:
2008/12/21 Peter Todd
If I could somehow arrange for the transform function to detect when it is being applied to a unevaluated thunk, and then modify the thunk in place, that would basically be the behavior I need. Any suggestions?
That is exactly what is already happening. Perhaps you want what you think is happening: if a value *is* evaluated, you want to apply the transformation right then instead of making a thunk.
Not quite. If I have a thunk, at the low level somewhere it must refer to the transform function, the transform matrix, and the element that is to be transformed. If I apply another transform to that unevaluated thunk, my understanding is that haskell will represent it as such: thunk transform Ta (thunk transform Tb e) When I want the following: thunk transform (Ta * Tb) e This alternate definition of the Element structure might make more sense: data Element = Element { elementOrigin :: V, elementSubs :: [Element] } | ElementThunk T Element transform :: T -> Element -> Element transform t (ElementThunk t2 e) = ElementThunk (tmul t t2) e transform t e = ElementThunk t e transform t e = Element { elementOrigin = tmulv t (elementOrigin e), elementSubs = map (transform t) (elementSubs e) } This gives a behavior close to what I want, applying a transform to an element results in a "thunk", and subsequent transforms simply modify the thunk, the problem is that I don't see a way to implicitly coerce an ElementThunk into an Element on demand for all the other code in the program that expects elements. (such as the elementOrigin function)
By the way, this is very operational thinking for Haskell. Haskell tries quite hard to abstract away operational thinking, so thinking on this level will be difficult and more work than you should be doing to write a program.
Yes, but this part of the program is library code, that will be used by a whole pile of other stuff, so if I can get the right behavior "magically" the rest of the program will be a lot easier to write. FWIW this is EDA software, those "elements" refer to elements of a printed circuit board layout, and the transform operations correspond to stuff like moving a chip on the board. The representation of a simple IC would consist of something like an element, with a bunch of sub-elements for each pin, all of which have geometry data.
May I ask why you want this behavior? Have you just tested it and observed that it is running too slowly and you are trying to speed it up?
I've written a previous version of this program in Python actually, where I explicitly modeled the lazy evaluation behavior that I wanted. It all worked great, but the overall speed was still quite slow. I was hoping that Haskell, built around lazy evaluation already, would be a better fit. That, and in any case, other aspects of the program that I've re-written in Haskell saw about a 5-1 redunction in code length... :) -- http://petertodd.org 'peter'[:-1]@petertodd.org