People,

(I wonder: is this for  beginn...@haskell.org ?)

I need to organize a  string interface  for a Haskell function  
Main.axiom  and a C program   
                            fifoFromA.c  

via a pair of  named pipes  (in Linux, UNIX).
The pipes are created before running, by the commands   > mkfifo toA
                                                        > mkfifo fromA
 
Main.axiom  outputs a  string  to  toA  and inputs the respond string 
                                            from  fromA  as the result.
fifoFromA  inputs a string from  toA, 
           converts it to the string  resStr,  outputs resStr to  fromA.

Main.axiom  must be able to be applied in a loop,
and there must be avoided repeated opening of a file/channel in a loop.
As an example, the string conversion in  fifoFromA.c  is put the 
conversion of each character to the lower case:

-------------------------- fifoFromA.c  ------------------------------
#include <string.h>
#include <stdio.h>
#include <fcntl.h>

#define BOUND 64

int main()
{
  int  toA, fromA, i, numread;
  char buf[BOUND];

  toA = open("toA", O_RDONLY);  fromA = open("fromA", O_WRONLY);

  for (;;)
  {
    numread = read(toA, buf, BOUND);
    buf[numread] = '\0';
    // printf("A:  Read from toA:  %s\n", buf);

    i = 0;                     // convert the string to the lower case
    while (i < numread) {buf[i] = tolower(buf[i]);  i++;}
    write(fromA, buf, strlen(buf));
  }
}
-----------------------------------------------------------------------

For the "to-A" part writen in C  (instead of Haskell), this interface 
loop works all right.
With Haskell, I manage to process only a single string in the loop, 
and then it ends with an error.

Main.hs  is given below.

I never dealt with such an IO in Haskell.
Can you, please, fix the code or give comments?

Please, copy the response to  mech...@botik.ru
(I am not in the list).

Thank you in advance for your notes,

------
Sergei
mech...@botik.ru



-------------------------------------------------------------------
import System.IO (IOMode(..), IO(..), Handle, openFile, hPutStr, 
                                              hGetLine, hFlush)
import System.IO.Unsafe (unsafePerformIO)

dir = showString "/home/mechvel/ghc/axiomInterface/byLowerLevel/"

toA_IO   = openFile (dir "toA")   WriteMode    :: IO Handle
fromA_IO = openFile (dir "fromA") ReadMode  
                                           -- used as global values
toA   = unsafePerformIO toA_IO             -- 
fromA = unsafePerformIO fromA_IO           --

axiomIO :: String -> IO String
axiomIO str = do
              hPutStr toA str 
              hFlush toA
              hGetLine fromA

axiom :: String -> String -> String
axiom str =  showString (unsafePerformIO $ axiomIO str)

-- Examples of usage --------------------------------------------
-- 
main = putStr (axiom "ABC1" "\n")    -- I

 -- putStr (axiom "ABC1" $ showChar '\n' $ axiom "ABC2" "\n")   -- II

 {- III:
    putStr (shows resPairs "\n")
       where
       n        = 9000
       str0     = "ABC"
       strings  = [str0 ++ (show i) | i <- [1 .. n]]
       resPairs = [(str, axiom str "") | str <- strings]
 -}
-----------------------------------------------------------------

I use  Glasgow Haskell  ghc-7.01.

Build:    > gcc -o fifoFromA fifoFromA.c
          > ghc --make Main

Running:  first, command     > ./fifoFromA
          on  terminal-2,
          then command       > ./Main
          on  terminal-1.

Now, the example  (I)  works  
-- in the sense that terminal-1 shows the result  "abc1"  
after the program on  terminal-2  is interrupted.

II and III do not work. And the aim is the examples like III.

_______________________________________________
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe

Reply via email to