Thanks for your comments.

Yes the server interface needs extended to handle other types.
When I put the interface together, I didn't feel that I knew what
I was doing - so I decided to do a fairly minimal interface as cleanly
as I knew how and see how it went.

I don't recall seeing your previous message but here's how I'd deal with
tricky datatypes like tuples.

Suppose you have a function F.bar :: Int -> (Int,String) which you want
 to call.

In Haskell, you might write something like this:

  case Foo.bar 42 of { (x,y) -> ... }

Which is more or less equivalent to this:

  let bar42 = Foo.bar 42 in
  case fst bar42 of { x -> 
  case snd bar42 of { y -> 
  ...
  }}

Which you can translate into C code like this:

  // first construct a thunk - like "let bar42 = Foo.bar 42 in ..."
  hugs->mkInt(42);                // push an argument
  hugs->lookupName("Foo","bar");  // push a function :: Int -> (Int,String)
  hugs->apply();                  // apply it
  bar42 = hugs->popHVal();        // remember for later

  // now extract first component
  hugs->pushHVal(bar42);
  hugs->lookupName("Prelude","fst");
  hugs->apply();
  x = hugs->evalInt();

  // now extract second component
  hugs->pushHVal(bar42);
  hugs->lookupName("Prelude","snd");
  hugs->apply();
  y = hugs->evalString();

The same approach should work for any other Haskell datatype: all you have to
 do is define some selector functions and you're away.

Two details - which I think you're alluding to:

1) We use a simple dynamic typing system to prevent some truly gruesome
   crashes.  If you add a new type, you have to tell the dynamic type system
   about it.  Look in hugs/lib/hugs/Dynamic.hs.

2) The dynamic typing system can't cope with polymorphic functions like fst
   and snd - so you have to create monomorphic instances and use them instead.

     myfst :: (Int,String) -> Int
     mysnd :: (Int,String) -> String
     myfst = fst
     mysnd = snd

   or you could use:

     hugs->compileExpr("Prelude.fst :: (Int,String) -> Int")

   which is easier to understand but is a bit slower and cannot 
   be used in the middle of an evaluation.

Alastair

> I have been making some use of hugs server. All of my functions pass
> down arguments which are integers or strings, and pass up pairs of
> integers and strings. In a previous message (a while back), I gave some
> information on taking apart the pairs. Originally I wanted to pass some
> other data type, but found that they didn't work (I didn't make a note
> of why not; I think I just get errors when I called hugs->clearError()).
> The restrictions seem to be:
>  - types declared using data Foo = ... don't work. Ones declared using
> type Foo = .. are OK.
>  - Int, String and Float are OK. Ptr is not.
> For my program, I can construct workrounds for these, albeit with a bit
> of overhead. So perhaps they can be noted as issues for later releases.
> 
> -- David
> 
> _______________________________________________________________________
> David Elworthy <[EMAIL PROTECTED]>
> Canon Research Centre Europe Ltd., Guildford, Surrey, UK
> URL: http://www.cre.canon.co.uk/
> Phone: +44 1483 448844; Fax: +44 1483 448845


Reply via email to