[Haskell-beginners] Implementing a Local Propagation Network

Stephen Blackheath [to Haskell-Beginners] mutilating.cauliflowers.stephen at blacksapphire.com
Wed May 19 18:55:04 EDT 2010


Patrick,

I think that looks like about the best way you could do it.  If I were
doing it, I would probably write it without the state monad, with all
the LPN ()'s becoming Network -> Network, and the code wouldn't be all
that different, except that 'multiplier' and 'adder' would become
slightly less readable.

If you did that, then in those cases (where your algorithm is described
by a sequence of modifications) you can say 'flip execState network $ do
...'.  Then all the 'revokeWire sum name's have to become 'modify $
revokeWire sum name'.

There's no particular reason why that's better - it's just style.  If
your main program is going to describe a whole lot of complex
transformations that happen in sequence, then your way would likely be
better than my suggested way.


Steve

On 20/05/10 07:12, Patrick LeBoutillier wrote:
> Stephen,
> 
> Thanks for the advice, finally I ended up using a State Monad and
> names (String) as symbolic references.
> 
> Here is what I came up with: http://pastebin.com/gqkP2sWy
> 
> Here is some test code:
> 
> import LPN
> import Control.Monad.State
> 
> testfc = snd $ runState fc networkMake
> 
> fc :: LPN ()
> fc = do
>   i:j:k:l:m:[] <- sequence $ map addWire ["i", "j", "k", "l", "m"]
>   f <- addIO "Fahrenheit" i
>   c <- addIO "Celsius" m
>   addConstant "32" 32 j
>   addConstant "5/9" (5/9) l
>   addAdder "+" j k i
>   addMultiplier "*" k l m
>   input f 212
> 
> At first it felt kind of messy, but as I kept refactoring and pushing
> stuff into the monad it became a lot cleaner and felt less heavy.
> I learned a lot about the State Monad doing this.
> 
> 
> Thanks,
> 
> Patrick
> 
> 
> 
> On Mon, May 17, 2010 at 10:41 PM, Stephen Blackheath [to
> Haskell-Beginners] <mutilating.cauliflowers.stephen at blacksapphire.com>
> wrote:
>> Patrick,
>>
>> If you want to implement it in a functional style, you have to use an
>> association map of some sort.  Haskell only has values, but not any
>> concept of a reference (unless you count things like IORef, but I am not
>> counting those).  Generally speaking this is needed whenever you are
>> dealing with a data structure that has cycles.  (Generally speaking
>> because it's possible to make data structures lazily refer to themselves.)
>>
>> People usually use IntMap, but there's a new package EnumMap on Hackage
>> which is really powerful.  It's like IntMap only typesafe.  You will
>> need a counter in your data structure as a source of unique ids.  You
>> can also use value-supply (from Hackage), which is a great bit of code.
>>
>> On the face of it, this seems cumbersome, but the way to do it is to
>> create a data structure and access it through accessor functions like
>> "add node", "delete node", "follow wire", etc.  This way you can
>> abstract those details away.  People have done various directed/undirect
>> graph packages and so on on Hackage - I can't recommend anything.
>>
>> Stick with it - this approach does work.  I've done things like
>> conversion of 3D models into triangle strips using this method, with
>> very satisfying results.
>>
>>
>> Steve
>>
>> On 18/05/10 12:59, Patrick LeBoutillier wrote:
>>> Hi all,
>>>
>>> After learning some Haskell recently, I decided to revisit a book
>>> about functional programming techniques for Perl: Higher Order Perl. I
>>> didn't fully understand the book at the time but now my Haskell
>>> experience has proved to be very insightful.
>>>
>>> Towards the end of the book the author implements a local propagation network.
>>>
>>> Here is the Perl source code:
>>> http://hop.perl.plover.com/Examples/Chap9/Local-Propagation/
>>> The PDF of the specific chapter is here:
>>> http://hop.perl.plover.com/book/pdf/09DeclarativeProgramming.pdf
>>>
>>> I would like to experiment with something similar in Haskell, but the
>>> way this network is designed is all about state and references:
>>>
>>> - Wires have a values that can change over time;
>>> - Wires have references to nodes;
>>> - Nodes have references to wires;
>>>
>>> I'm a bit stuck as to how to approach the "object has a list
>>> references to other objects" situation from Haskell. I tried this:
>>>
>>> type Name = String
>>> data Node = Node Name [Wire]
>>> data Wire = Wire Name Node Double [Node]
>>>
>>> But that doesn't seem like it would work since when I change a Wire I
>>> must find all "copies" of it (in the Node objects) and update them
>>> also. Perhaps I should just refer to Wires/Nodes by name and use an
>>> association list to lookup them up, but that seems cumbersome.
>>>
>>> Anybody have any suggestions?
>>>
>>>
>>> Thanks a lot,
>>>
>>> Patrick
>>>
>>>
>>>
>> _______________________________________________
>> Beginners mailing list
>> Beginners at haskell.org
>> http://www.haskell.org/mailman/listinfo/beginners
>>
> 
> 
> 


More information about the Beginners mailing list