People,
(I wonder: is this for beginners@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
#include
#include
#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 mechvel@botik.ru
(I am not in the list).
Thank you in advance for your notes,
------
Sergei
mechvel@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.