> Yes, I've run into this before. In fact this is one of those tricky
> problems where you can't quite get tail-recursion where you want it:
> (pseudo-ish code follows)
>
> peekCString ptr = do
> x <- peek ptr
> if x == '\0' then return [] else do
> xs <- peekCString (ptr + 1)
> return (x:xs)
>
> Any ideas? I seem to recall the ML folks have a hack for dealing with
> this.
Off the top of my head:
1) Compute length of C string.
(As usual, need to use seq on the '+1' argument.)
2) Scan from right to left, constructing the list.
peekCString ptr = do
l <- lenCString ptr 0
peekCString' ptr l []
lenCString ptr n = seq n $ do
c <- peek (ptr+n)
if c=='\0'
then return n
else lenCString ptr (n+1)
peekCString' ptr 0 r = return r
peekCString' ptr (n+1) r = do
c <- peek (ptr+n)
peekCString' ptr n (c:r)
I don't think this will leak.
Or, since making two passes seems ugly, construct the list in reverse and then
return the reversed list:
peekCString ptr = peekCString' ptr []
where
peekCString' ptr r = do
c <- peek ptr
if c == '\0'
then return (reverse r)
else peekCString' (ptr+1) (c:r)
I have a nasty feeling that reverse doesn't work in constant stack space
though so this probably doesn't work.
--
Alastair
_______________________________________________
Glasgow-haskell-bugs mailing list
[EMAIL PROTECTED]
http://www.haskell.org/mailman/listinfo/glasgow-haskell-bugs